Ответ 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
заметно быстрее - с небольшим массивом, подобным этому, дополнительные уровни вызовов функций делают большую разницу во времени.