Python numpy: размер [0] в векторах (n-dim) против массивов (nxn-dim)
Мне сейчас интересно, как ведет себя массив numpy. Я чувствую, что размеры не согласуются с векторами (размерность Nx1
) до "реальных массивов" (размерность NxN
).
Я не понимаю, почему это не работает:
a = array(([1,2],[3,4],[5,6]))
concatenate((a[:,0],a[:,1:]), axis = 1)
# ValueError: all the input arrays must have same number of dimensions
Кажется, что :
(в 1:]
) имеет значение, но (:0
не работает)
Заранее спасибо!
Detailled Version: Поэтому я ожидал бы, что shape(b)[0]
ссылается на вертикальное направление в (массивы Nx1
), как в массиве 2D (NxN
). Но похоже, что размер [0]
- это горизонтальное направление в массивах (массивы Nx1
)?
from numpy import *
a = array(([1,2],[3,4],[5,6]))
b = a[:,0]
print shape(a) # (3L, 2L), [0] is vertical
print a # [1,2],[3,4],[5,6]
print shape(b) # (3L, ), [0] is horizontal
print b # [1 3 5]
c = b * ones((shape(b)[0],1))
print shape(c) # (3L, 3L), I'd expect (3L, 1L)
print c # [[ 1. 3. 5.], [ 1. 3. 5.], [ 1. 3. 5.]]
Что я ошибся? Есть ли лучший способ, чем
d = b * ones((1, shape(b)[0]))
d = transpose(d)
print shape(d) # (3L, 1L)
print d # [[ 1.], [ 3.], [ 5.]]
получить (Nx1
) вектор, который я ожидаю или хочу?
Здесь есть две общие проблемы. Во-первых, b
не является (N, 1)
образным массивом, это массив (N,)
. В numpy 1D и 2D массивы - разные вещи. 1D массивы просто не имеют направления. Вертикальные или горизонтальные, строки и столбцы - это 2D-концепции.
Второе связано с тем, что называется " трансляция ". В массивах numpy вы можете транслировать низкоразмерные массивы на более крупные, а нижнемерная часть применяется элементарно к высокомерному.
Правила вещания довольно просты:
При работе на двух массивах NumPy сравнивает свои фигуры по элементам. Он начинается с конечных размеров и работает вперёд. Два измерения совместимы, когда
они равны или
один из них - 1
В вашем случае он начинается с последнего измерения ones((shape(b)[0],1))
, который равен 1
. Это соответствует второму критерию. Поэтому он умножает массив b
elementwise для каждого элемента из ones((shape(b)[0],1))
, в результате чего получается 3D-массив.
Таким образом, это примерно эквивалентно:
c = np.array([x*b for x in ones(shape(b))])
Редактировать:
Чтобы ответить на ваш первоначальный вопрос, вы хотите сохранить как первый, так и второй массивы в виде 2D-массивов.
numpy
есть очень простое правило для этого: индексирование уменьшает количество измерений, нарезка - нет. Так что вам нужно только иметь 1-й фрагмент. Поэтому в вашем примере просто измените a[:,0]
на a[:,:1]
. Это означает, что "каждый столбец до второго". Конечно, это включает только первый столбец, но он по-прежнему считается операцией среза, а не получает элемент, поэтому он все еще сохраняет количество измерений:
>>> print(a[:, 0])
[1 3 5]
>>> print(a[:, 0].shape)
(3,)
>>> print(a[:, :1])
[[1]
[3]
[5]]
>>> print(a[:, :1].shape)
(3, 1)
>>> print(concatenate((a[:,:1],a[:,1:]), axis = 1))
[[1 2]
[3 4]
[5 6]]