2016-08-02 21 views
4

Ich habe zwei Numpy-Arrays x mit Form (m, i) und y mit Form (m, j) (also die Anzahl der Zeilen ist die gleiche). Ich möchte jede Spalte von x mit jeder Spalte von y elementweise so multiplizieren, dass das Ergebnis die Form (m, i*j) hat.Multiplizieren Sie jede Spalte von 2D-Array mit jeder Spalte von einem anderen 2D-Array

Beispiel:

import numpy as np 

np.random.seed(1) 
x = np.random.randint(0, 2, (10, 3)) 
y = np.random.randint(0, 2, (10, 2)) 

Dies erstellt die folgenden zwei Arrays x:

array([[1, 1, 0], 
     [0, 1, 1], 
     [1, 1, 1], 
     [0, 0, 1], 
     [0, 1, 1], 
     [0, 0, 1], 
     [0, 0, 0], 
     [1, 0, 0], 
     [1, 0, 0], 
     [0, 1, 0]]) 

und y:

array([[0, 0], 
     [1, 1], 
     [1, 1], 
     [1, 0], 
     [0, 0], 
     [1, 1], 
     [1, 1], 
     [1, 1], 
     [0, 1], 
     [1, 0]]) 

Jetzt sollte das Ergebnis sein:

array([[0, 0, 0, 0, 0, 0], 
     [0, 0, 1, 1, 1, 1], 
     [1, 1, 1, 1, 1, 1], 
     [0, 0, 0, 0, 1, 0], 
     [0, 0, 0, 0, 0, 0], 
     [0, 0, 0, 0, 1, 1], 
     [0, 0, 0, 0, 0, 0], 
     [1, 1, 0, 0, 0, 0], 
     [0, 1, 0, 0, 0, 0], 
     [0, 0, 1, 0, 0, 0]]) 

Derzeit ich diesen Vorgang mit zwei verschachtelten Schleifen über den Spalten von x und y implementiert haben:

def _mult(x, y): 
    r = [] 
    for xc in x.T: 
     for yc in y.T: 
      r.append(xc * yc) 
    return np.array(r).T 

Aber ich bin ziemlich sicher, dass es eine elegantere Lösung sein, dass ich Es scheint nicht so zu sein.

Antwort

6

Verwendung NumPy broadcasting -

(y[:,None]*x[...,None]).reshape(x.shape[0],-1) 

Erklärung

Als Eingänge, haben wir -

y : 10 x 2 
x : 10 x 3 

Mit y[:,None], führen wir eine neue Achse zwischen den beiden bestehenden dimmt, so Erstellen einer 3D Array-Version davon. Dies hält die erste Achse als erste in 3D Version und schiebt die zweite Achse als dritte.

Mit x[...,None] führen wir als letzte eine neue Achse ein, indem wir die zwei vorhandenen Dims als erste zwei Dims hochschieben, um eine 3D Array-Version zu erhalten.

Zusammengefasst mit der Einführung der neuen Achsen, haben wir -

y : 10 x 1 x 2 
x : 10 x 3 x 1 

Mit y[:,None]*x[...,None] gibt broadcasting sowohl für y und x sein würde, mit einer Form von (10,3,2) in einer Ausgangsanordnung zur Folge hat. Um zum endgültigen Ausgabe-Array der Form (10,6) zu gelangen, müssen wir nur die letzten zwei Achsen mit dieser Umformung zusammenführen.

+0

"komplizierter" Hack aber sehr prägnant! +1 –

+0

können Sie hier eine Erklärung hinzufügen? es ist knapp aber nicht erklärend. – kmario23

+0

@ kmario23 Eine Erklärung hinzugefügt, schau es dir an! – Divakar