2017-09-28 1 views
0

Ich habe eine 3D-Daten und möchte Durchschnittsprodukt von Datenpunkten in allen möglichen Entfernungen vom Ursprung berechnen. Ich habe ein riesiges Raster (128^3-1024^3) und was ich jetzt mache, gibt keine Antwort in Stunden.Berechnungen mit numpy roll über 3D-Daten

# u read from a file 
import numpy as np 
for icx in range(0,128): 
    for icy in range(0,128): 
     for icz in range(0,128): 
      cukin[icx,icy,icz] = np.mean((u*np.roll(np.roll(np.roll(u,icx, axis=0),icy, axis=1),icz, axis=2)) 

Gibt es eine Möglichkeit, Schleifen in diesem Problem zu vermeiden?

Toy Beispiel:

cukin = np.zeros((2,2,2)) 
u = np.mgrid[1:5:1,1:5:1,1:5:1] 
for icx in range(0,2): 
    for icy in range(0,2): 
     for icz in range(0,2): 
      cukin[icx,icy,icz] = np.mean((u*np.roll(np.roll(np.roll(u,icx, axis=0),icy, axis=1),icz, axis=2))) 

Gibt cukin

[[[ 7.5 7. ] 
    [ 7. 6.5 ]] 

[[ 6.25 6.25] 
    [ 6.25 6.25]]] 
+0

Sie können den Roll-Befehl vereinfachen: 'np.roll (a, (i, j, k))' ist gültig. – VBB

+0

@VBB das würde Schleifen immer noch nicht vermeiden. Das Durchlaufen von Schleifen ist zeitaufwendig. –

+0

Machen Sie eine Spielzeugversion Ihres Programms mit eingegebenen Daten, damit wir es ausführen können. –

Antwort

0

Versuchen Iteratoren statt Listen mit (range erstellt eine Liste), sie verbrauchen viel weniger Speicher. Um über alle Positionsindizes gleichzeitig zu iterieren, können Sie itertools.product verwenden. Auch rollen alle Achsen zur gleichen Zeit statt verschachtelte np.roll dreimal zu rufen:

from itertools import product as prod 
import numpy as np 

rng_x = xrange(128) 
rng_y = xrange(128) 
rng_z = xrange(128) 
xyz_ids = prod(rng_x, rng_y, rng_z) 

# NOTE: the order of the axis in numpy arrays is inverse 
for i, j, k in xyz_ids: 
    cukin[k, j, i] = np.mean(u * np.roll(u, [k, j, i], axis=[0, 1, 2])) 

Nicht sicher, ob ausgeben wird, was Sie erwarten. Lass mich wissen ob es funktioniert. Sie sollten überlegen, ein Beispiel dafür hinzuzufügen, was u und die entsprechende erwartete Ausgabe ist.

+0

Das vermeidet Schleifen immer noch nicht, also braucht viel Zeit. Ich habe die Frage mit einem Spielzeugbeispiel aktualisiert. –

+0

Sie können Listenkompressen immer verwenden: 'cukin = np.array ([np.mean (u * np.roll (u, [k, j, i], Achse = [0, 1, 2])) für i , j, k in xyz_ids]). shape (2, 2, 2) ' –

+0

aber ich denke, es läuft immer noch über 3 Loops? Es dauert genauso lange! –