2017-08-05 13 views
0

Nehmen wir an, ich habe eine Matrix X (1000x10) und eine Matrix Y (20x10). Ich möchte effizient Y zu jedem (20x10) Block von X wiederholt hinzufügen (daher 50 Blöcke). Gibt es eine effiziente Möglichkeit, dies mit Numpy zu tun? Ich möchte nicht np.repeat verwenden, da die ursprünglichen Matrizen riesig sind und ich unnötige Vervielfältigung von Y verhindern möchte. Irgendwelche Ideen?Numpy fügen Sie eine Matrix zu Scheiben einer anderen Matrix

Antwort

2

Sie argument list unpacking nutzen können, NumPy broadcasting und the fact that ndarray.reshape() returns a view die Operation auszuführen:

tmp = X.reshape(-1, *Y.shape) 
tmp += Y 

keine zusätzlichen Daten zugeordnet werden und nach diesen Operationen X enthält das Ergebnis der Operation.

+1

Der Unterschied besteht darin, dass die Berechnung von 'X.reshape() + Y' zuordnet und ein neues Array erstellt, während' tmp + = Y' die bereits zugewiesenen Werte ändert. Kein zusätzlicher RAM wird zugewiesen. Und die Ausgabe hat die richtige Form, da 'X' niemals seine Form ändert. –

+0

Bekam es. Vielen Dank. –

+0

Wow! Das sieht magisch für mich aus! wie funktioniert es? Kannst du erklären, was ist "Y.shape"? und warum 'X.reshape (-1, * Y.shape)' 'X' nicht in' tmp' kopiert? (Ist es wie ein Bezug auf 'X')? Vielen Dank! – Babak

0

Sie können np.tile verwenden, um „zu erweitern“ (genauer gesagt, Kachel) die kleinere Array die Größe des größeren Arrays entsprechen, zum Beispiel

x = np.zeros([1000,10]) 
y = np.ones([20,10]) 
new_x = x + np.tile(y,(50,1)) 

Dieses eine temporäre große Array im Speicher erstellen wird fügen Sie zu x hinzu, aber wird sofort weggeworfen, also hängt es von Ihrer Gedächtniskapazität und der Größe des Feldes ab, aber ich glaube, dass es das in Bezug auf CPU-Verbrauch und Lesbarkeit am leistungsfähigsten ist. Die andere Möglichkeit besteht natürlich darin, über das größere Array zu schleifen und das kleinere Array auf jedes Teil davon zu übertragen (in diesem Fall 50 Mal), aber es wird in Bezug auf die CPU zeitaufwendiger und weniger effizient sein, aber es wird im Gedächtnis leichter sein.

Ein Beispiel für die zweite Option:

for i in range(0,len(x),20): 
    x[i:i+20,:] = y