2015-05-04 13 views
6

Es scheint, dass ich in etwas potenziell albern verloren bin. Ich habe ein n-dimensionales numpy Array und ich möchte es mit einem Vektor (1d Array) entlang einer Dimension multiplizieren (was sich ändern kann!). Als Beispiel sagen, dass ich entlang der Achse eines 2D-Arrays von einem 1D-Array multiplizieren möchten 0 des ersten Arrays, ich etwas tun kann:Multiplizieren numpy ndarray mit 1d Array entlang einer gegebenen Achse

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

Einfach, aber ich möchte diese Idee erweitern n-Dimensionen (für a, während b immer 1d ist) und zu jeder Achse. Mit anderen Worten, ich würde gerne wissen, wie man eine Scheibe mit der np.newaxis an der richtigen Stelle erzeugt. Sagen, dass ein 3D ist, und ich möchte entlang der Achse multiplizieren = 1, würde Ich mag die Scheibe erzeugen, die korrekt geben würde:

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

D.h. Angesichts der Anzahl der Dimensionen eine (etwa 3), und die Achse, entlang der I (etwa Achse = 1) multiplizieren sollen, wie geben I erzeugen und die Scheibe:

np.newaxis,:,np.newaxis 

Dank.

+0

Können Sie etwas mehr über das, was Sie damit erreichen wollen, erklären? –

+0

Ich habe Daten auf einem ndarray, und ich möchte die Daten mit einem Filter entlang einer Achse multiplizieren. –

Antwort

6

Lösungscode -

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 

Probelauf für eine Demo der Schritte -

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 

Jetzt möchten wir element Multiplikationen entlang given axis = 1 auszuführen. Lassen Sie uns erstellen 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]) 

Schließlich umformen b & das elementweise Multiplikation durchführen:

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

Schauen Sie sich die whos Informationen wieder und achten Sie besonders auf 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, meine Schuld habe ich nicht erwähnt: Ich kann keine Kopien von b mit passender Größe erzeugen, da a sehr, sehr groß sein kann. –

+0

Hey, nein, Entschuldigung, es ist tatsächlich eine Lösung, ich hatte es falsch verstanden. Vielen Dank! –

+0

@AJC Es ist in Ordnung, wirklich! Entfernen meines früheren Kommentars – Divakar

2

Du könntest b Erstellen Sie ein Slice-Objekt und wählen Sie die gewünschte Dimension aus:

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] 
Verwandte Themen