2016-06-25 2 views
1

Ich habe eine Frage darüber, wie man eine Matrix parallel füllt. Ich versuche es in Python Zeile für Zeile. Aber die Zeit, um es parallel zu tun, ist am schlechtesten als die sequentielle Verarbeitungszeit. Wie kann ich es effizient machen? Hinweis: Ich muss den Wert der Indizes kennen (i und j).Eine Matrix parallel füllen

Squential

def something(pos, size): 
    global matrix 

    numpy.zeros(shape=(size, size)) 

    for i in xrange(size): 
     matrix[i][i] = 0.0 

     i_lat = pos[i]['lat'] 
     i_lon = pos[i]['lon'] 

     for j in xrange(i + 1, size): 
      matrix[j][i] = matrix[i][j] = _matrix_update(pos, i_lat, i_lon, i, j) 

def _matrix_update(pos, lat, lon, u, v): 
    return 0.0 if u == v else euclidean_distance((lat, lon), (pos[v]['lat'], pos[v]['lon'])) 

Parallel

def something(pos, size): 
    global matrix 

    numpy.zeros(shape=(size, size)) 

    for i in xrange(size): 
     matrix[i][i] = 0.0 

     i_lat = pos[i]['lat'] 
     i_lon = pos[i]['lon'] 

     Parallel(n_jobs=mp.cpu_count())(delayed(_matrix_update)(pos, i_lat, i_lon, i, j) for j in xrange(i, size)) 

def _matrix_update(pos, lat, lon, u, v): 
    global matrix 
    matrix[u][v] = matrix[v][u] = (0.0 if u == v else euclidean_distance((lat, lon), (pos[v]['lat'], pos[v]['lon']))) 
+0

Ich denke, dass es in einer vektorisierten Art und Weise ohne Schleife gemacht werden kann. Können Sie Ihre Frage mit einer Beispiel-Eingabematrix aktualisieren (5 Zeilen sollten ausreichen), eine kurze Beschreibung dessen, was Sie mit diesen Daten machen möchten und die gewünschte resultierende Matrix? – MaxU

+0

Sie können auch überprüfen, dass [die] (http://docs.scipy.org/doc/scipy-0.14.0/reference/spatial.distance.html) _vectorized_ Funktionen – MaxU

+0

In diesem Fall kann ich nicht Numpy verwenden , weil die euclidean_distance-Funktion eine geeignete Methode für diesen Fall ist und kein Framework es so implementiert, wie ich es brauche. – user3108967

Antwort

2

Ihr Code wirft eine ganze Reihe von Fragen, zu viele, um in den Kommentaren zu stellen.

def something(pos, size): 
    global matrix  

Was ist matrix? Warum global? Da Sie es mutieren, brauchen Sie das Globale nicht, auch wenn es außerhalb dieser Funktion definiert ist. Aber ich würde es lieber sehen, wenn es als Argument hin und her geht.

numpy.zeros(shape=(size, size)) 

Was ist der Sinn dieser Aussage? Warum ordnen Sie das Ergebnis nichts zu? Es soll matrix = np.zeros(shape...) sein? In diesem Fall wird matrix in der Funktion erstellt und sollte in einer return matrix-Anweisung, nicht global sein.

for i in xrange(size): 
     matrix[i][i] = 0.0 

Wenn matrix 2D-Array ist, dann indiziert mit matrix[i,i] = 0. Aber wenn es mit dem zeros Ausdruck erstellt wurde, diagonal dies ist bereits 0.

 i_lat = pos[i]['lat'] 
     i_lon = pos[i]['lon'] 

Was ist pos? Die Syntax legt nahe, dass es sich um ein strukturiertes Array handelt, das Feld "lat" des i-ten Datensatzes. Es ist keine Liste von Wörterbüchern?

 for j in xrange(i + 1, size): 
      matrix[j][i] = matrix[i][j] = _matrix_update(pos, i_lat, i_lon, i, j) 

Hier stellen Sie also symmetrische Werte ein. Wenn dies iterativ getan wird, ist dies ein guter Weg, dies zu tun. Die sind np.tri... Funktionen für den Umgang mit oberen und unteren Dreiecksfeldern.

def _matrix_update(pos, lat, lon, u, v): 
    return 0.0 if u == v else euclidean_distance((lat, lon), (pos[v]['lat'], pos[v]['lon'])) 

Bedenkt man, wie man auf i und j durchlaufen, u==v nie auftritt, so kann die Aktualisierung

j_lat, j_lon = pos[j]['lat'], pos[j]['lon'] 
matrix[j,i] = matrix[i,j] = euclidean_distance((i_lat, i_lon), (j_lat, j_lon)) 

Ich erwarte, dass diese Änderungen nicht zu

vereinfacht werden, um die Berechnung zu beschleunigen, aber sie sollten mach es klarer.

Was ist das Parallel? Sie müssen mehr Informationen darüber geben, welches Modul oder Paket Sie verwenden. Ist das etwas, das versucht, mehrere Kerne zu verwenden? Ist es etwas, das bekannt ist, mit matrix (was auch immer es ist) zu arbeiten?

Was ist das euclidian_distance Funktion? Von woanders importiert?