Chciałbym połączyć kilka warunków, aby wybrać wiersz / kolumny z tablicy.

Biorąc pod uwagę matrycę {x0}}, wiem o tym

A[:, [1,3]] 

Daje mi drugą i czwartą kolumnę. Również,

A[:, :3]

Działa jak marzenie. Jednak nie połączyłem warunków:

A[:, [:3, 6, 7]]

Daje mi błąd składni. Jak mogę uzyskać ten wybór?

4
FooBar 15 sierpień 2014, 17:44

2 odpowiedzi

Najlepsza odpowiedź

W skrócie możesz zrobić:

A[:, range(3) + [6, 7]]

Lub

A[:, np.r_[:3, 6, 7]]

Aby zrozumieć, dlaczego twoja pierwsza próba nie działała, musisz zrozumieć trochę więcej o tym, jak ogólne indeksowanie Python i jak działa indeksowanie Numpy.


Po pierwsze, krojenie Notacja jest ważna tylko wewnątrz plasterka, więc blah = [:3, 6, 7] jest nieprawidłową składnią Python, ponieważ konstruując nową listę w takim przypadku. (Domycznie robisz to za pomocą A[:, [:3, 6, 7]] : np.r_. Na przykład:

In [1]: print np.r_[:3, 6, 7]
[0 1 2 6 7]

Zauważ, że możemy uzyskać więcej - mniejszy wynik ({X0}} zwraca tablicę, następny przykład powróci list), dodając dwie listy razem:

In [2]: print range(3) + [6, 7]
[0, 1, 2, 6, 7]

Jednak ważne jest również, aby zrozumieć, co dzieje się za zasłonami z numpry. Istnieją dwa ogólne typy indeksowania w numpry. "Normalny" indeksowanie wykorzystuje plasterki dowolnego rodzaju i zwraca widok tablicy. Dane nie są skopiowane. Indeksowanie "Fantazyjne" wykorzystuje dowolną sekwencję elementów (np. Lista) i kopiuje dane.

Ponieważ wszystko, co można opisać według standardowej notacji krojenia, ma regularne kroki (tj. Interwał początkowy, końcowy i krokowy), możesz wykonać nową tablicę bez kopiowania oryginalnych danych. (Obiekty numpy muszą być "regularnie stronami" w pamięci. Możesz nawiązać odniesienie do "Co trzeci przedmiot" bez kopiowania danych, ale nie "pozycji 2, 5 i 6", ponieważ nie ma regularnego wzorca do tego ostatniego.)

Wszystko to może wydawać się mylące, ale oto przykład dlaczego ma znaczenie. Zróbmy przykładową tablicę i pokroić to dwa różne (ale równoważne) sposoby:

In [1]: a = np.arange(18).reshape(3, 6)

In [2]: a
Out[2]:
array([[ 0,  1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10, 11],
       [12, 13, 14, 15, 16, 17]])

In [3]: b = a[:, :3]

In [4]: b
Out[4]:
array([[ 0,  1,  2],
       [ 6,  7,  8],
       [12, 13, 14]])

In [5]: c = a[:, [0, 1, 2]]

In [6]: c
Out[6]:
array([[ 0,  1,  2],
       [ 6,  7,  8],
       [12, 13, 14]])

b i c wyglądają identycznie. Jednak c jest nową kopią danych w a, gdy b odnosi się do oryginalnych danych. Jeśli zmienimy c, a nie zostanie zmodyfikowany:

In [7]: c[0, 0] = 10000

In [8]: c
Out[8]:
array([[10000,     1,     2],
       [    6,     7,     8],
       [   12,    13,    14]])

In [9]: a
Out[9]:
array([[ 0,  1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10, 11],
       [12, 13, 14, 15, 16, 17]])

Jeśli zmienamy b, a {EM> zostanie zmodyfikowany :

In [10]: a
Out[10]:
array([[ 0,  1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10, 11],
       [12, 13, 14, 15, 16, 17]])

In [11]: b[0,0] = 99999

In [12]: a
Out[12]:
array([[99999,     1,     2,     3,     4,     5],
       [    6,     7,     8,     9,    10,    11],
       [   12,    13,    14,    15,    16,    17]])

In [13]: b
Out[13]:
array([[99999,     1,     2],
       [    6,     7,     8],
       [   12,    13,    14]])

Daje to dużo kontroli nad użyciem pamięci i umożliwia dość wydajne (jest to naprawdę ważne, gdy zaczniesz pracować z bardzo dużymi tablicami w pamięci). Jednak można go spalić, jeśli nie jesteś świadomy tego, co się dzieje.

5
Joe Kington 15 sierpień 2014, 14:37

Nie jestem pewien, czy tego szukasz:

>>> A = numpy.array([range(10)]*10)
>>> numpy.hstack((A[:, :3],A[:, [6,7]]))
array([[0, 1, 2, 6, 7],
       [0, 1, 2, 6, 7],
       [0, 1, 2, 6, 7],
       [0, 1, 2, 6, 7],
       [0, 1, 2, 6, 7],
       [0, 1, 2, 6, 7],
       [0, 1, 2, 6, 7],
       [0, 1, 2, 6, 7],
       [0, 1, 2, 6, 7],
       [0, 1, 2, 6, 7]])
>>> 
0
Vor 15 sierpień 2014, 14:17