ValueError: все входные массивы должны иметь одинаковое количество измерений

У меня проблема с np.append.

Я пытаюсь дублировать последний столбец матрицы 20x361 n_list_converted, используя следующий код:

n_last = []
n_last = n_list_converted[:, -1]
n_lists = np.append(n_list_converted, n_last, axis=1)

Но я получаю ошибку:

ValueError: все входные массивы должны иметь одинаковое количество измерений

Однако, я проверил размеры матрицы, выполнив

 print(n_last.shape, type(n_last), n_list_converted.shape, type(n_list_converted))

и я получаю

(20L,) (20L, 361L)

чтобы размеры соответствовали? Где ошибка?

Ответ 1

Если я начинаю с массива 3x4 и конкатенирует массив 3x1, с осью 1, я получаю массив 3x5:

In [911]: x = np.arange(12).reshape(3,4)
In [912]: np.concatenate([x,x[:,-1:]], axis=1)
Out[912]: 
array([[ 0,  1,  2,  3,  3],
       [ 4,  5,  6,  7,  7],
       [ 8,  9, 10, 11, 11]])
In [913]: x.shape,x[:,-1:].shape
Out[913]: ((3, 4), (3, 1))

Обратите внимание, что оба входа для конкатенации имеют 2 измерения.

Опустите :, а x[:,-1] - форма (3) - это 1d и, следовательно, ошибка:

In [914]: np.concatenate([x,x[:,-1]], axis=1)
...
ValueError: all the input arrays must have same number of dimensions

Код для np.append (в этом случае, когда указана ось)

return concatenate((arr, values), axis=axis)

Итак, с небольшим изменением синтаксиса append работает. Вместо списка требуется 2 аргумента. Он имитирует список append является синтаксисом, но его не следует путать с этим методом списка.

In [916]: np.append(x, x[:,-1:], axis=1)
Out[916]: 
array([[ 0,  1,  2,  3,  3],
       [ 4,  5,  6,  7,  7],
       [ 8,  9, 10, 11, 11]])

np.hstack сначала гарантирует, что все входы atleast_1d, а затем объединяет:

return np.concatenate([np.atleast_1d(a) for a in arrs], 1)

Поэтому для этого требуется тот же вход x[:,-1:]. По сути, это же действие.

np.column_stack также выполняет конкатенацию на оси 1. Но сначала она пропускает 1d входов через

array(arr, copy=False, subok=True, ndmin=2).T

Это общий способ превратить этот массив (3) в массив (3,1).

In [922]: np.array(x[:,-1], copy=False, subok=True, ndmin=2).T
Out[922]: 
array([[ 3],
       [ 7],
       [11]])
In [923]: np.column_stack([x,x[:,-1]])
Out[923]: 
array([[ 0,  1,  2,  3,  3],
       [ 4,  5,  6,  7,  7],
       [ 8,  9, 10, 11, 11]])

Все эти "стеки" могут быть удобными, но в конечном счете важно понимать размеры и базу np.concatenate. Также знайте, как искать код для таких функций. Я часто использую магию ipython ??.

И во время тестов np.concatenate заметно быстрее - с небольшим массивом, подобным этому, дополнительные уровни вызовов функций делают большую разницу во времени.

Ответ 2

(n,) и (n, 1) не имеют одинаковой формы. Попробуйте отличить вектор к массиву с помощью обозначения [:, None]:

n_lists = np.append(n_list_converted, n_last[:, None], axis=1)

В качестве альтернативы при извлечении n_last вы можете использовать

n_last = n_list_converted[:, -1:]

чтобы получить массив (20, 1).

Ответ 3

Причина, по которой вы получаете свою ошибку, состоит в том, что матрица "1 по n" отличается от массива длины n.

Вместо этого рекомендую использовать hstack() и vstack(). Вот так:

import numpy as np
a = np.arange(32).reshape(4,8) # 4 rows 8 columns matrix.
b = a[:,-1:]                    # last column of that matrix.

result = np.hstack((a,b))       # stack them horizontally like this:
#array([[ 0,  1,  2,  3,  4,  5,  6,  7,  7],
#       [ 8,  9, 10, 11, 12, 13, 14, 15, 15],
#       [16, 17, 18, 19, 20, 21, 22, 23, 23],
#       [24, 25, 26, 27, 28, 29, 30, 31, 31]])

Обратите внимание на повторяющийся столбец "7, 15, 23, 31". Также обратите внимание, что вместо a[:,-1] я использовал a[:,-1:]. Моя версия генерирует столбец:

array([[7],
       [15],
       [23],
       [31]])

Вместо строки array([7,15,23,31])


Изменить: append() работает намного медленнее. Прочитайте этот ответ.

Ответ 4

Вы также можете привести (n,) к (n, 1), заключив в скобки [].

Например, вместо np.append(b,a,axis=0) используйте np.append(b,[a],axis=0)

a=[1,2]
b=[[5,6],[7,8]]
np.append(b,[a],axis=0)

возвращается

array([[5, 6],
       [7, 8],
       [1, 2]])