Scipyで3Dデータを補間するときにパフォーマンスを改善する方法
-
22-09-2019 - |
質問
私は大気を表す3D-dataを持っています。次に、このデータを一般的なZ座標に補間したいと思います(それによって私が意味することは、関数の教義から明らかにする必要があります)。次のコードは正常に機能しますが、パフォーマンスを改善する方法があるのではないかと思っていました...
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
解決
まあ、これは、より少ないメモリを使用するからといって、小さなスピードアップを与えるかもしれません。
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
私がやったことは、GRとDAを本当に取り除くことだけです。
それ以外は、この関数を大きく異なる値で呼び出していますか(つまり、値は異なりますが、他のパラメーターは同じです)?もしそうなら、関数を複数の値を処理できるようにすることをお勧めします(言い換えれば、値の長さと同じ長さの場合、RETに別の次元を追加します)。次に、作成した補間関数をよりよく利用しています。
最後の提案は、試すことです プロファイラー. 。これにより、何が最も時間がかかるかを確認できます。
所属していません StackOverflow