2014-06-05 14 views
6

Betrachten Sie den folgenden Code numpy Arrays, die sehr langsam ist:Beschleunigen Sie eine anzahlmäßige Schleife in Python?

# Intersection of an octree and a trajectory 
def intersection(octree, trajectory): 
    # Initialize numpy arrays 
    ox = octree.get("x") 
    oy = octree.get("y") 
    oz = octree.get("z") 
    oe = octree.get("extent")/2 
    tx = trajectory.get("x") 
    ty = trajectory.get("y") 
    tz = trajectory.get("z") 
    result = np.zeros(np.size(ox)) 
    # Loop over elements 
    for i in range(0, np.size(tx)): 
     for j in range(0, np.size(ox)): 
      if (tx[i] > ox[j]-oe[j] and 
       tx[i] < ox[j]+oe[j] and 
       ty[i] > oy[j]-oe[j] and 
       ty[i] < oy[j]+oe[j] and 
       tz[i] > oz[j]-oe[j] and 
       tz[i] < oz[j]+oe[j]): 
       result[j] += 1 
    # Finalize 
    return result 

So wird die Funktion neu zu schreiben, die Berechnung zu beschleunigen? (np.size(tx) == 10000 und np.size(ox) == 100000)

+0

Ziehen Sie auch die Verwendung von OpenCL in Betracht? –

+0

Ich brauche keine volle Leistung, ich will nur eine rohe Geschwindigkeit. – Vincent

+1

Erstellen Sie einen 'scipy.spatial.KDTree' aus den Punkten tx, ty, tz und verwenden Sie dann die Suche nach dem nächsten Nachbarn in der Unendlichkeitsnorm für jeden Punkt in ox, oy, oz, um festzustellen, ob ein Punkt nahe genug ist. –

Antwort

6

Sie sind Zuteilung 10000 Listen Größe 100000. Das erste, was zu tun wäre, mit range für die verschachtelte j Schleife zu stoppen und die Generator-Version xrange stattdessen verwenden. Dies spart Ihnen Zeit und Platz bei der Allokierung all dieser Listen.

Der nächste wäre vektorisiert Operationen zu verwenden:

for i in xrange(0, np.size(tx)): 
    index = (ox-oe < tx[i]) & (ox+oe > tx[i]) & (oy-oe < ty[i]) & (oy+oe > ty[i]) & (oz-oe < tz[i]) & (oz+oe > tz[i]) 
    result[index] += 1 
+0

Änderung erfolgt, aber es bietet keine enorme Geschwindigkeit – Vincent

+0

Gib mir eine Sekunde, da ist die nächste kommen :) –

+0

Ok, die vektorisierte Form ist in (muss möglicherweise Bedingungen überprüfen), aber als Sie Ihre Frage als Antwort auf meine ursprüngliche Antwort geändert haben, wurde dieser Teil der Antwort irrelevant, obwohl es immer noch ein guter erster Schritt im Falle von nicht holprigen Daten wäre :) –

0

ich denke, das wird das gleiche Ergebnis für die doppelte Schleife geben und schneller sein:

for j in xrange(np.size(ox)): 
    result[j] += sum(abs(tx-ox[j])<oe[j] & abs(ty-oy[j])<oe[j] & abs(tz-oz[j])<oe[j]) 

Um dies zu erhalten: 1) neu ordnet die Schleifen (dh Swap-t Saum), was gilt, da sich in den Schleifen nichts ändert; 2) ziehen result[j] außerhalb der i Schleife; 3) wandle alle t>ox-oe and t<ox+oe in abs(t-ox)<oe um (obwohl das keine große Beschleunigung sein kann, ist es einfacher zu lesen).

Da Sie keinen ausführbaren Code haben, und ich wollte keinen Test dafür erstellen, bin ich nicht 100% sicher, dass das korrekt ist.

Verwandte Themen