Odpowiedzi:
>>> test[:,0]
array([1, 3, 5])
Podobnie,
>>> test[1,:]
array([3, 4])
umożliwia dostęp do wierszy. Jest to omówione w sekcji 1.4 (Indeksowanie) odniesienia NumPy . Jest to szybkie, przynajmniej z mojego doświadczenia. Jest to z pewnością znacznie szybsze niż dostęp do każdego elementu w pętli.
A jeśli chcesz uzyskać dostęp do więcej niż jednej kolumny na raz, możesz:
>>> 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]])
test[:,[0,2]]
po prostu uzyskuje dostęp do danych, np. test[:, [0,2]] = something
zmodyfikuje test, a nie utworzy kolejnej tablicy. Ale copy_test = test[:, [0,2]]
tak naprawdę tworzy kopię, jak mówisz.
test[:,[0,2]]
po prostu uzyskuje dostęp do danych, a test[:, [0, 2]][:, [0, 1]]
nie? Wydaje się bardzo nieintuicyjne, że zrobienie tego samego ponownie przynosi różne rezultaty.
>>> test[:,0]
array([1, 3, 5])
to polecenie daje wektor wiersza, jeśli po prostu chcesz go zapętlić, jest w porządku, ale jeśli chcesz hstackować z inną tablicą o wymiarze 3xN, będziesz mieć
ValueError: all the input arrays must have same number of dimensions
podczas
>>> test[:,[0]]
array([[1],
[3],
[5]])
daje wektor kolumny, dzięki czemu można wykonać operację konkatenacji lub operacji hstack.
na przykład
>>> np.hstack((test, test[:,[0]]))
array([[1, 2, 1],
[3, 4, 3],
[5, 6, 5]])
Możesz także transponować i zwrócić wiersz:
In [4]: test.T[0]
Out[4]: array([1, 3, 5])
Aby uzyskać kilka niezależnych kolumn, wystarczy:
> test[:,[0,2]]
dostaniesz kolumny 0 i 2
Chociaż pytanie zostało udzielone, pozwól mi wspomnieć o kilku niuansach.
Załóżmy, że interesuje Cię pierwsza kolumna tablicy
arr = numpy.array([[1, 2],
[3, 4],
[5, 6]])
Jak już wiesz z innych odpowiedzi, aby uzyskać go w postaci „wektora wiersza” (tablica kształtu (3,)
), używasz krojenia:
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
Aby sprawdzić, czy tablica jest widokiem, czy kopią innej tablicy, możesz wykonać następujące czynności:
arr_c1_ref.base is arr # True
arr_c1_copy.base is arr # False
patrz ndarray.base .
Oprócz oczywistej różnicy między nimi (modyfikacja arr_c1_ref
wpłynie arr
), liczba kroków bajtów dla przejścia każdego z nich jest inna:
arr_c1_ref.strides[0] # 8 bytes
arr_c1_copy.strides[0] # 4 bytes
patrz kroki . Dlaczego to jest ważne? Wyobraź sobie, że masz bardzo dużą tablicę A
zamiast arr
:
A = np.random.randint(2, size=(10000,10000), dtype='int32')
A_c1_ref = A[:, 1]
A_c1_copy = A[:, 1].copy()
i chcesz obliczyć sumę wszystkich elementów pierwszej kolumny, tj . A_c1_ref.sum()
lub A_c1_copy.sum()
. Korzystanie ze skopiowanej wersji jest znacznie szybsze:
%timeit A_c1_ref.sum() # ~248 µs
%timeit A_c1_copy.sum() # ~12.8 µs
Wynika to z różnej liczby wspomnianych wcześniej kroków:
A_c1_ref.strides[0] # 40000 bytes
A_c1_copy.strides[0] # 4 bytes
Chociaż może się wydawać, że użycie kopii kolumnowych jest lepsze, nie zawsze jest to prawdą, ponieważ wykonanie kopii zajmuje dużo czasu i zajmuje więcej pamięci (w tym przypadku jej utworzenie zajęło mi około 200 µs A_c1_copy
). Jednak jeśli potrzebujemy kopii w pierwszej kolejności lub musimy wykonać wiele różnych operacji na konkretnej kolumnie tablicy i nie mamy nic przeciwko poświęceniu pamięci dla szybkości, to zrobienie kopii jest dobrym rozwiązaniem.
W przypadku, gdy jesteśmy zainteresowani pracą głównie z kolumnami, dobrym pomysłem może być utworzenie naszej tablicy w kolejności kolumnowej („F”) zamiast w kolejności rzędnej („C”) (która jest domyślna ), a następnie wykonaj wycinanie jak poprzednio, aby uzyskać kolumnę bez kopiowania:
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
Teraz wykonanie operacji sumowania (lub dowolnej innej) w widoku kolumny jest znacznie szybsze.
Na koniec pragnę zauważyć, że transpozycja tablicy i stosowanie wycinania wierszy jest tym samym, co użycie wycinania kolumn na oryginalnej tablicy, ponieważ transpozycja odbywa się poprzez zamianę kształtu i kroków oryginalnej tablicy.
A.T[1,:].strides[0] # 40000
>>> test
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
>>> ncol = test.shape[1]
>>> ncol
5L
Następnie możesz wybrać 2–4 kolumnę w ten sposób:
>>> test[0:, 1:(ncol - 1)]
array([[1, 2, 3],
[6, 7, 8]])