2015-05-04 18 views
6

Wydaje się, że gubię się w czymś potencjalnie głupim. Mam n-wymiarową tablicę numpy i chcę ją pomnożyć przez wektor (tablicę 1d) wzdłuż jakiegoś wymiaru (który może się zmienić!). Jako przykład, że chcę, aby pomnożyć 2d tablicy przez 1d tablicy wzdłuż osi 0 z pierwszej tablicy, mogę zrobić coś takiego:Multiply numpy ndarray z tablicą 1d wzdłuż danej osi

a=np.arange(20).reshape((5,4)) 
b=np.ones(5) 
c=a*b[:,np.newaxis] 

łatwe, ale chciałbym rozszerzyć ten pomysł n-wymiary (dla a, podczas gdy b jest zawsze 1d) i do dowolnej osi. Innymi słowy, chciałbym wiedzieć, jak wygenerować plaster z np.newaxis w odpowiednim miejscu. Powiedzieć, że jest 3d i chce się rozmnażać wzdłuż osi = 1, to, że, aby wygenerować plastra które prawidłowo podać:

c=a*b[np.newaxis,:,np.newaxis] 

Tj biorąc pod uwagę liczbę wymiarów (powiedzmy 3), a oś, wzdłuż której chcę, aby pomnożyć (słownie oś = 1), w jaki sposób mogę wygenerować i przejść kawałek:

np.newaxis,:,np.newaxis 

Dzięki.

+0

Czy mógłbyś wyjaśnić nieco więcej o tym, co próbujesz osiągnąć przez to? –

+0

Mam dane na tablicy ndarray i chciałbym pomnożyć dane z filtrem wzdłuż niektórych osi. –

Odpowiedz

6

Rozwiązanie Code -

import numpy as np 

# Given axis along which elementwise multiplication with broadcasting 
# is to be performed 
given_axis = 1 

# Create an array which would be used to reshape 1D array, b to have 
# singleton dimensions except for the given axis where we would put -1 
# signifying to use the entire length of elements along that axis 
dim_array = np.ones((1,a.ndim),int).ravel() 
dim_array[given_axis] = -1 

# Reshape b with dim_array and perform elementwise multiplication with 
# broadcasting along the singleton dimensions for the final output 
b_reshaped = b.reshape(dim_array) 
mult_out = a*b_reshaped 

run Przykładowy demo schodów -

In [149]: import numpy as np 

In [150]: a = np.random.randint(0,9,(4,2,3)) 

In [151]: b = np.random.randint(0,9,(2,1)).ravel() 

In [152]: whos 
Variable Type  Data/Info 
------------------------------- 
a   ndarray 4x2x3: 24 elems, type `int32`, 96 bytes 
b   ndarray 2: 2 elems, type `int32`, 8 bytes 

In [153]: given_axis = 1 

Teraz chcielibyśmy wykonać mnożenia elementwise wzdłuż given axis = 1. Stwórzmy dim_array:

In [154]: dim_array = np.ones((1,a.ndim),int).ravel() 
    ...: dim_array[given_axis] = -1 
    ...: 

In [155]: dim_array 
Out[155]: array([ 1, -1, 1]) 

Wreszcie przekształcenia b & wykonać mnożenie elementwise:

In [156]: b_reshaped = b.reshape(dim_array) 
    ...: mult_out = a*b_reshaped 
    ...: 

Sprawdź whos informacji ponownie i zwrócić szczególną uwagę na b_reshaped & mult_out:

In [157]: whos 
Variable  Type  Data/Info 
--------------------------------- 
a   ndarray 4x2x3: 24 elems, type `int32`, 96 bytes 
b   ndarray 2: 2 elems, type `int32`, 8 bytes 
b_reshaped ndarray 1x2x1: 2 elems, type `int32`, 8 bytes 
dim_array ndarray 3: 3 elems, type `int32`, 12 bytes 
given_axis int  1 
mult_out  ndarray 4x2x3: 24 elems, type `int32`, 96 bytes 
+0

Ok, moja wina, nie wspomniałem o tym: Nie mogę wygenerować kopii b o odpowiednim rozmiarze pasującym do a, ponieważ może być bardzo duże. –

+0

Hej, nie, przepraszam, to jest rozwiązanie, źle to zrozumiałem. Wielkie dzięki! –

+0

@AJC Jest naprawdę dobrze! Usuwanie mojego wcześniejszego komentarza. – Divakar

2

Mógłbyś b uild obiekt slice i wybierz pożądany wymiar w tym:

import numpy as np 

a = np.arange(18).reshape((3,2,3)) 
b = np.array([1,3]) 

ss = [None for i in range(a.ndim)] 
ss[1] = slice(None) # set the dimension along which to broadcast 

print ss # [None, slice(None, None, None), None] 

c = a*b[ss] 
Powiązane problemy