2016-06-07 9 views
5

Angenommen, ich habe die folgenden zwei Felder:Summe der quadratischen Differenz zwischen 2 Numpy Arrays

import numpy as np 
a=np.asarray([[1,2,4], 
     [3,1,2]]) 
b=np.asarray([[2,1,1], 
     [3,2,3], 
     [4,1,2], 
     [2,2,1],]) 

Für jede Zeile a_row in a, würde Ich mag die Summe der quadratischen Differenz zwischen a_row und jede Zeile in b erhalten . Das resultierende Array wäre ein 2 mal 4 Array. Das erwartete Ergebnis wäre die folgende:

array([[ 11., 5., 14., 10.], 
     [ 2., 2., 1., 3.]]) 

Ich habe bereits eine Lösung mit Schleife implementiert:

c=np.zeros((2,4)) 
for e in range(a.shape[0]): 
    c[e,:] = np.sum(np.square(b-a[e,:]),axis=1) 
print c 

Was ich brauche, ist eine voll vektorisiert Lösung, das heißt keine Schleife erforderlich ist.

+0

Scheint wie eine natürliche für Lambda-Ausdrücke und Verschlüsse. – duffymo

Antwort

3

ist ein Numpythonic Ansatz, indem einfach die b Umformung um in der Lage sein, um direkt die a davon zu subtrahieren:

>>> np.square(b[:,None] - a).sum(axis=2).T 
array([[11, 5, 14, 10], 
     [ 2, 2, 1, 3]]) 
+0

Hallo Kasravand, danke für deine Antwort. Es funktioniert mit dem Beispiel-Array, aber ich habe einen Speicherfehler in meinen tatsächlichen Skripten. In meinen Skripten ist die Form von Array a (500,3072) und bs Form (5000,3072). Ich nehme an, es ist wahrscheinlich, weil diese Methode speicherintensiv ist? Ich habe den Fehler nicht mit der in meiner Frage erwähnten Schleifenmethode erhalten. – Allen

+0

@Allen Ich schlage 2 Wege vor, zuerst, wenn Sie nicht mit großen Zahlen zu tun haben, können Sie Ihr Array [type] konvertieren (http://docs.scipy.org/doc/numpy-1.10.1/user/basics. types.html) zu einem einfacheren Typ wie 'int8', wenn es nicht möglich ist, können Sie Ihr Array in kürzere Arrays aufteilen und die Operation mit ihnen separat ausführen, dann verketten Sie das Ergebnis. Hier ist eine gute Antwort http://stackoverflow.com/questions/31268998/how-to-merge-two-large-numpy-arrays-if-slicing-doesnt-resolve-memory-error – Kasramvd

3

Wenn Sie Zugriff auf SciPy, dann könnten Sie tun:

import scipy 
from scipy.spatial.distance import cdist 

import numpy as np 

a=np.asarray([[1,2,4], 
     [3,1,2]]) 
b=np.asarray([[2,1,1], 
     [3,2,3], 
     [4,1,2], 
     [2,2,1],]) 

x = cdist(a,b)**2 
# print x 
# array([[ 11., 5., 14., 10.], 
#  [ 2., 2., 1., 3.]]) 

Dies verwendet die cdist Funktion, die vektorisiert und schnell. Sie können mit numba oder cython möglicherweise etwas schneller werden, aber das hängt von der Größe Ihrer Arrays in der Praxis ab. Hier

+0

Danke Josh. Ich habe getestet und es funktioniert gut. In diesem Fall brauche ich jedoch eine vollständig vektorisierte Lösung. d. h. Scipy-Funktion kann nicht verwendet werden. – Allen

Verwandte Themen