Перебор столбцов массива в виде векторов столбцов

#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 документы по индексированию.

https://numpy.org/doc/stable/reference/arrays.indexing.html

Ответ №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])