Как получить доступ к i-му столбцу многомерного массива NumPy?

Предположим, что у меня есть:

test = numpy.array([[1, 2], [3, 4], [5, 6]])

test[i] получает i-й строку массива (например, [1, 2]). Как я могу получить доступ к i-му столбцу? (например, [1, 3, 5]). Кроме того, будет ли это дорогостоящей операцией?

Ответ 1

>>> test[:,0]
array([1, 3, 5])

Аналогично,

>>> test[1,:]
array([3, 4])

позволяет вам обращаться к строкам. Это описано в разделе 1.4 (Индексация) ссылки NumPy. Это быстро, по крайней мере, в моем опыте. Это, конечно, намного быстрее, чем доступ к каждому элементу цикла.

Ответ 2

И если вы хотите получить доступ к нескольким столбцам за раз, вы могли бы сделать:

>>> test = np.arange(9).reshape((3,3))
>>> test
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])
>>> test[:,[0,2]]
array([[0, 2],
       [3, 5],
       [6, 8]])

Ответ 3

>>> test[:,0]
array([1, 3, 5])

эта команда дает вам вектор-строку, если вы просто хотите ее перебрать, это хорошо, но если вы хотите hstack с другим массивом с размером 3xN, у вас будет

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

а

>>> test[:,[0]]
array([[1],
       [3],
       [5]])

дает вам вектор-столбец, так что вы можете выполнять операцию конкатенации или hstack.

например.

>>> np.hstack((test, test[:,[0]]))
array([[1, 2, 1],
       [3, 4, 3],
       [5, 6, 5]])

Ответ 4

Вы также можете транспонировать и возвращать строку:

In [4]: test.T[0]
Out[4]: array([1, 3, 5])

Ответ 5

Чтобы получить несколько независимых столбцов, просто:

> test[:,[0,2]]

вы получите столбцы 0 и 2

Ответ 6

Хотя на вопрос дан ответ, позвольте мне упомянуть некоторые нюансы.

Допустим, вы заинтересованы в первом столбце массива

arr = numpy.array([[1, 2],
                   [3, 4],
                   [5, 6]])

Как вы уже знаете из других ответов, чтобы получить его в виде "вектора строки" (массив shape (3,)), вы используете нарезку:

arr_c1_ref = arr[:, 1]  # creates a reference to the 1st column of the arr
arr_c1_copy = arr[:, 1].copy()  # creates a copy of the 1st column of the arr

Чтобы проверить, является ли массив представлением или копией другого массива, вы можете сделать следующее:

arr_c1_ref.base is arr  # True
arr_c1_copy.base is arr  # False

см. ndarray.base.

Помимо очевидного различия между ними (изменение arr_c1_ref повлияет на arr), количество шагов в байтах для обхода каждого из них различно:

arr_c1_ref.strides[0]  # 8 bytes
arr_c1_copy.strides[0]  # 4 bytes

видеть успехи. Почему это важно? Представьте, что у вас есть очень большой массив A вместо arr:

A = np.random.randint(2, size=(10000,10000), dtype='int32')
A_c1_ref = A[:, 1] 
A_c1_copy = A[:, 1].copy()

и вы хотите вычислить сумму всех элементов первого столбца, т.е. A_c1_ref.sum() или A_c1_copy.sum(). Использование скопированной версии намного быстрее:

%timeit A_c1_ref.sum()  # ~248 µs
%timeit A_c1_copy.sum()  # ~12.8 µs

Это связано с разным количеством шагов, упомянутых ранее:

A_c1_ref.strides[0]  # 40000 bytes
A_c1_copy.strides[0]  # 4 bytes

Хотя может показаться, что лучше использовать копии столбцов, это не всегда так, потому что создание копии занимает много времени и требует больше памяти (в этом случае мне понадобилось около 200 мкс для создания A_c1_copy). Однако, если нам нужна копия в первую очередь, или нам нужно выполнить много разных операций с определенным столбцом массива, и мы в порядке с потерей памяти ради скорости, то создание копии - это путь.

В случае, если мы заинтересованы в работе в основном со столбцами, было бы неплохо создать наш массив в мажорном столбце ('F'), а не в мажорном ряду ('C') (по умолчанию), а затем выполните нарезку, как раньше, чтобы получить столбец, не копируя его:

A = np.asfortranarray(A)  # or np.array(A, order='F')
A_c1_ref = A[:, 1]
A_c1_ref.strides[0]  # 4 bytes
%timeit A_c1_ref.sum()  # ~12.6 µs vs ~248 µs

Теперь выполнение операции суммирования (или любой другой) в представлении столбцов выполняется намного быстрее.

Наконец, позвольте мне заметить, что транспонирование массива и использование нарезки строк - это то же самое, что использование нарезки столбцов в исходном массиве, потому что транспонирование выполняется просто путем замены формы и шагов исходного массива.

A.T[1,:].strides[0]  # 40000

Ответ 7

>>> test
array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]])

>>> ncol = test.shape[1]
>>> ncol
5L

Затем вы можете выбрать 2-й столбец следующим образом:

>>> test[0:, 1:(ncol - 1)]
array([[1, 2, 3],
       [6, 7, 8]])

Ответ 8

                    test=numpy.array([[1,2],[3,4],[5,6]])
                    print(test)
                     output:[[1 2]-->0th index row
                         [3 4]-->1st index row
                         [5 6]]-->2nd index row
                          | |
                          0 1 columns.
            so we've 3 rows and 2 columns.
                    >>>test[:,0]
                           array([1,3,5])
                    >>>test[2,:]
                          array([5,6])


    **1Q)how to access [1,3,5]**
                    A)you want [1,3,5] as out put,i.e all rows elements and only 0th column elements. 
                     so we've to use test[:,0]. i.e. test[rows,columns]
                Here ':' indicates all rows,0 indicates 0th column 
   **2Q)How to access [5,6]**
A)you want access [5,6],it is in row wise 3rd row(i.e 2nd index row) and columns wise 0,1 columns(i.e all columns),to access this we use below code.
        test[2,:]
    In this way we access rows and columns values.