2015-09-24 10 views
7

Próbuję znaleźć zgrabny mały trik do krojenia wiersza/kolumny z tablicy 2d i uzyskania tablicy (col_size x 1) lub (1 x row_size).Numpy - krojenie wektora z 2 wierszy lub kolumn z tablicy

Czy jest łatwiejszy sposób niż użycie numpy.reshape() po każdym krojeniu?

Cheers, Stephan

+0

Czy możesz podać przykład oczekiwanego wejścia i wyjścia? Czy chcesz uzyskać tablicę 1D lub tablicę 2D? –

+0

Oczywiście! Załóżmy, że mam tablicę typu 'np.ones ((2,40))'. Z tej tablicy chcę wyciąć cały wiersz w postaci 'np.array ((1,40)). Wynik powinien być tablicą 2d – neurotronix

+1

Użyj np.newaxis lub None, aby wstawić nową oś –

Odpowiedz

11

można pokroić i włożyć nową oś w jednej operacji. Przykładowo, poniżej znajduje się w tablicy 2D:

>>> a = np.arange(1, 7).reshape(2, 3) 
>>> a 
array([[1, 2, 3], 
     [4, 5, 6]]) 

celu kawałek z jednego kolumna (powrót tablicy kształtu (2, 1)) plasterka None w trzecim wymiarze:

>>> a[:, 1, None] 
array([[2], 
     [5]]) 

kroić OUT pojedynczy wiersz (zwracająca tablica kształtu (1, 3)), plasterek z None jako drugi wymiar:

>>> a[0, None, :] 
array([[1, 2, 3]]) 
+0

Wielkie dzięki! Dokładnie to, czego potrzebowałem! Numpy jest naprawdę świetny i szybki, a przynajmniej nie bardzo intuicyjny, przynajmniej dla mnie. – neurotronix

+1

Bez problemu! Indeksowanie/przekształcanie zajmuje trochę czasu, aby owinąć głowę (przynajmniej dla mnie), ale ma sens po odrobinie praktyki. The [docs] (http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html) są całkiem niezłe do wyjaśnienia, co się tutaj dzieje (sekcja * podstawowe cięcie *). –

+0

Co ciekawe, nigdy nie pomyślałem o połączeniu indeksowania z dodatkiem "None". Sądzę, że to tylko siła przyzwyczajenia, użycie 'None' do rozszerzenia wymiarów istniejącej macierzy. I jest szybciej. – hpaulj

6

Bądź indeks kawałek, lista lub tablica

X[[0],:] 
    X[0:1,4] 

Ale nie ma nic złego w reshape innych niż fakt, że wymaga pisanie. To nie jest powolne. [None,:] to dobra krótka ręka.

Zastosowanie wskaźnika listy może być najkrótszej, ale nie wytwarzać kopię (plus lub minus a) i wolniej

Na tablicy (100,100) całkowitą:

In [487]: timeit x[[50],:] 
100000 loops, best of 3: 10.3 µs per loop # slowest 

In [488]: timeit x[50:51,:] 
100000 loops, best of 3: 2.24 µs per loop # slice indexing is fast 

In [489]: timeit x[50,:].reshape(1,-1) 
100000 loops, best of 3: 3.29 µs per loop # minimal time penalty 

In [490]: timeit x[50,:][None,:] 
100000 loops, best of 3: 3.55 µs per loop 

In [543]: timeit x[None,50,:]   # **best** 
1000000 loops, best of 3: 1.76 µs per loop 

jeden test do kopiowania jest porównanie wskaźnika bufora danych z oryginałem.

In [492]: x.__array_interface__['data'] 
Out[492]: (175920456, False) 
In [493]: x[50,:].__array_interface__['data'] 
Out[493]: (175940456, False) 
In [494]: x[[50],:].__array_interface__['data'] 
Out[494]: (175871672, False) # different pointer 
In [495]: x[50:51,:].__array_interface__['data'] 
Out[495]: (175940456, False) 
In [496]: x[50,:][None,:].__array_interface__['data'] 
Out[496]: (175940456, False) 
+0

Dziękuję kolego! – neurotronix

+0

Problem polega na tym, że wdrażam skalowalną sieć neuronową, skalowalną pod względem rozmiarów warstw. Dzięki 'reshape' musiałem uzyskać dostęp do bardzo często różnych atrybutów instancji (np. Rozmiarów warstw). Wreszcie, aby to naprawić: kiedy użyję 'a [0, None,:]' do wycięcia wiersza z 'tablica' a, czy zwróci kopię? – neurotronix

+1

'[0, None,:]' zwraca widok. – hpaulj

1

Co powiesz na ten miły i łatwy sposób?

In [73]: arr = (np.arange(5, 25)).reshape(5, 4) 

In [74]: arr 
Out[74]: 
array([[ 5, 6, 7, 8], 
     [ 9, 10, 11, 12], 
     [13, 14, 15, 16], 
     [17, 18, 19, 20], 
     [21, 22, 23, 24]]) 

# extract column 1 as a column vector 
In [79]: col1 = arr[:, [0]] 
In [80]: col1.shape 
Out[80]: (5, 1) 

In [81]: col1 
Out[81]: 
array([[ 5], 
     [ 9], 
     [13], 
     [17], 
     [21]]) 


# extract row 1 as a row vector 
In [82]: row1 = arr[[0], :] 

In [83]: row1.shape 
Out[83]: (1, 4) 

In [84]: row1 
Out[84]: array([[5, 6, 7, 8]]) 
+0

Dziękuję za czystą i szczegółową odpowiedź! Ale czy nie zauważyłeś, że pytanie ma więcej niż dwa lata? Pozdrawiam :) – neurotronix

+0

@neurotronix Właśnie to sobie uświadomiłem. W każdym razie, ze względów pedagogicznych, czas nigdy nie ma znaczenia;) – kmario23

+0

To prawda, dziękuję za poświęcenie czasu na odpowiedź! – neurotronix

Powiązane problemy