#python #numpy
#python #numpy
Вопрос:
Есть ли способ перебирать столбцы 2D-массива numpy таким образом, чтобы итераторы оставались векторами столбцов?
т.е.
>>> A = np.arange(9).reshape((3,3))
[[0 1 2]
[3 4 5]
[6 7 8]]
>>> np.hstack([a in some_way_of_iterating(A)])
[[0 1 2]
[3 4 5]
[6 7 8]]
Это полезно, например, когда я хочу передать векторы столбцов в функцию, которая преобразует отдельный вектор столбца, не загромождая его изменениями
Ответ №1:
Как насчет простого транспонирования:
B = np.hstack([a.reshape(-1,1) for a in A.T])
Вам нужно .reshape(-1,1)
получить размер n X 1
, а не просто n
Ответ №2:
In [39]: A = np.arange(1,10).reshape(3,3)
In [40]: A
Out[40]:
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
Итерация по массиву работает с первым измерением. Это очень похоже на итерацию по вложенному списку, но медленнее. И, как и в случае со списком, это тоже уменьшает размерность.
Вы можете выполнять итерации по диапазону и использовать расширенную индексацию [i]
для поддержания 2d-формы «вектор столбца»:
In [41]: [A[:,[i]] for i in range(3)]
Out[41]:
[array([[1],
[4],
[7]]),
array([[2],
[5],
[8]]),
array([[3],
[6],
[9]])]
Или итерация по транспонированию — но для этого все еще требуется некоторая форма reshape
. Я предпочитаю None/newaxis
синтаксис.
In [42]: [a[:,None] for a in A.T]
Out[42]:
[array([[1],
[4],
[7]]),
array([[2],
[5],
[8]]),
array([[3],
[6],
[9]])]
Индексирование и изменение формы можно комбинировать с:
In [43]: A[:,0,None]
Out[43]:
array([[1],
[4],
[7]])
Или с нарезкой:
In [44]: A[:,1:2]
Out[44]:
array([[2],
[5],
[8]])
Есть разница, которая может иметь значение. A[:,[i]]
создает копию, A[:,i,None]
является view
.
Возможно, пришло время перечитать основные numpy
документы по индексированию.
Ответ №3:
Уродливый, но другой возможный способ с index
и transpose
:
np.hstack([A[:,i][np.newaxis].T for i in range(len(A.T))])
Я использую np.newaxis
для облегчения транспонирования. Основываясь на предложении @hpaulj, это можно значительно очистить:
np.hstack([A[:,i,np.newaxis] for i in range(A.shape[1])])
Вывод:
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
Комментарии:
1.
A[:, i, np.newaxis]
не так уродливо. Такжеrange(A.shape[1])