So verbessern Sie die Leistung beim Interpolieren von 3D -Daten mit Scipy
-
22-09-2019 - |
Frage
Ich habe 3D-Daten, die die Atmosphäre repräsentieren. Jetzt möchte ich diese Daten in eine gemeinsame Z -Koordinate interpolieren (was ich damit meine, sollte aus der Lehre der Funktion klar sein). Der folgende Code funktioniert gut, aber ich habe mich gefragt, ob es eine Möglichkeit gab, die Leistung zu verbessern ...
def interpLevel(grid,value,data,interp='linear'):
"""
Interpolate 3d data to a common z coordinate.
Can be used to calculate the wind/pv/whatsoever values for a common
potential temperature / pressure level.
grid : numpy.ndarray
The grid. For example the potential temperature values for the whole 3d
grid.
value : float
The common value in the grid, to which the data shall be interpolated.
For example, 350.0
data : numpy.ndarray
The data which shall be interpolated. For example, the PV values for
the whole 3d grid.
kind : str
This indicates which kind of interpolation will be done. It is directly
passed on to scipy.interpolate.interp1d().
returs : numpy.ndarray
A 2d array containing the *data* values at *value*.
"""
ret = np.zeros_like(data[0,:,:])
# we need to copy the grid to a new one, because otherwise the flipping
# done below will be messed up
gr = np.zeros_like(grid)
da = np.zeros_like(data)
for latIdx in xrange(grid.shape[1]):
for lonIdx in xrange(grid.shape[2]):
# check if we need to flip the column
if grid[0,latIdx,lonIdx] > grid[-1,latIdx,lonIdx]:
gr[:,latIdx,lonIdx] = grid[::-1,latIdx,lonIdx]
da[:,latIdx,lonIdx] = data[::-1,latIdx,lonIdx]
else:
gr[:,latIdx,lonIdx] = grid[:,latIdx,lonIdx]
da[:,latIdx,lonIdx] = data[:,latIdx,lonIdx]
f = interpolate.interp1d(gr[:,latIdx,lonIdx], \
da[:,latIdx,lonIdx], \
kind=interp)
ret[latIdx,lonIdx] = f(value)
return ret
Lösung
Nun, dies könnte eine kleine Beschleunigung geben, nur weil es weniger Speicher verwendet.
ret = np.zeros_like(data[0,:,:])
for latIdx in xrange(grid.shape[1]):
for lonIdx in xrange(grid.shape[2]):
# check if we need to flip the column
if grid[0,latIdx,lonIdx] > grid[-1,latIdx,lonIdx]:
ind = -1
else:
ind = 1
f = interpolate.interp1d(grid[::ind,latIdx,lonIdx], \
data[::ind,latIdx,lonIdx], \
kind=interp)
ret[latIdx,lonIdx] = f(value)
return ret
Alles, was ich getan habe, ist wirklich Gr und DA loszuwerden.
Ansonsten nennen Sie diese Funktion mit vielen unterschiedlichen Werten (dh Wert sind unterschiedlich, aber andere Parameter gleich)? In diesem Fall möchten Sie möglicherweise die Funktion in der Lage sein, mehrere Werte zu verarbeiten (fügen Sie eine andere Dimension mit anderen Worten hinzu, die so lange wie die Wertelänge dauern). Dann nutzen Sie die von Ihnen erstellte Interpolationsfunktion besser.
Der letzte Vorschlag ist es zu versuchen ein Profiler. Dadurch können Sie sehen, was die meiste Zeit in Anspruch nimmt.