2012-01-17 16 views
23

Mam dwa numpy tablice o trzech wymiarach (3 x 4 x 5) i chcę je połączyć, więc wynik ma cztery wymiary (3 x 4 x 5 x 2). W Matlab można to zrobić za pomocą cat(4, a, b), ale nie w Numpy.Połączyć dwa numpy tablice w czwartym wymiarze

Na przykład:

a = ones((3,4,5)) 
b = ones((3,4,5)) 
c = concatenate((a,b), axis=3) # error! 

Aby wyjaśnić, życzę c[:,:,:,0] i c[:,:,:,1] odpowiadać oryginalnych dwóch tablic.

Odpowiedz

4

Co

c = np.stack((a,b), axis=3) 
+1

Ta funkcja została dodana w wersji numpy w wersji 1.10 i uczyniła tę operację bardziej elegancką. –

1

Działa to dla mnie:

c = numpy.array([a,b]) 

Chociaż byłoby miło, gdyby pracowała na swój sposób też.

+0

Próbowałem, ale to skutkuje A (2 x 3 x 4 x 5) tablica. Blisko, ale nie do końca. –

12

Jak o następujące elementy:

c = concatenate((a[:,:,:,None],b[:,:,:,None]), axis=3) 

Daje to (3 x 4 x 5 x 2) tablicę, która moim zdaniem jest rozplanowany w sposób Państwo potrzebują.

Tutaj None jest synonimem np.newaxis: Numpy: Should I use newaxis or None?

edycji Jak sugeruje @Joe Kington, kod może być czyszczone trochę przy użyciu wielokropka:

c = concatenate((a[...,None],b[...,None]), axis=3) 
+0

pokonaj mnie o kilka sekund. . .dammit :-) Będę winić za wypisanie 'np.newaxis', zamiast' None' +1 do ciebie – JoshAdel

+0

@JoshAdel: LOL, ale zaoszczędziłeś na tym, że nie musisz pisać tych denerwujących dwukropków! :-) – NPE

+0

Działa jak urok. –

27

Tutaj przejść:

import numpy as np 
a = np.ones((3,4,5)) 
b = np.ones((3,4,5)) 
c = np.concatenate((a[...,np.newaxis],b[...,np.newaxis]),axis=3) 
+3

Zaakceptowanie tego dla bycia nieco bardziej czytelnym. Poza tym, wyłudził mi moją nieznajomość operatora '...'. –

+7

Jeśli masz sekwencję tablic, które chcesz ułożyć w stos w ten sposób, możesz użyć: 'c = np.concatenate ([aux [..., np.newaxis] dla Aux w sequence_of_arrays], axis = 3)' –

+6

Więcej ogólnie można użyć 'axis = -1', niezależnie od liczby wymiarów w oryginalnej tablicy. –

0

To niekoniecznie najbardziej elegancki, ale ja użyłam odmiany

c = rollaxis(array([a,b]), 0, 4) 

w przeszłości.

8

Przyjęta wyżej odpowiedź jest świetna. Dodam jednak następujące rzeczy, ponieważ jestem dorkiem matematyki i miło jest korzystać z tego, że a.shape jest... tj. wykonanie transpozycji odwraca kolejność indeksów tablicy numpy. Więc jeśli masz swoje cegiełki w tablicy o nazwie bloków, a następnie roztwór powyżej jest:

new = np.concatenate([block[..., np.newaxis] for block in blocks], 
        axis=len(blocks[0].shape)) 

ale można też zrobić

new2 = np.array([block.T for block in blocks]).T 

który myślę brzmi bardziej gładko. Warto zauważyć, że już zaakceptowane odpowiedź biegnie szybciej:

%%timeit 
new = np.concatenate([block[..., np.newaxis] for block in blocks], 
        axis=len(blocks[0].shape)) 
1000 loops, best of 3: 321 µs per loop 

podczas

%%timeit 
new2 = np.array([block.T for block in blocks]).T 
1000 loops, best of 3: 407 µs per loop 
+1

To piękne, kreatywne rozwiązanie. –

+0

To jest to, czego potrzebowałem i jest agnostyczny dla całkowitej liczby wymiarów dla dowolnej tablicy numpy. Dzięki! – rayryeng

Powiązane problemy