假设我有一座山上3个(已知)高度的气象站的数据。具体地说,每个站点每分钟在其位置记录一次温度测量。我有两种插值,我想要执行。我希望能够快速地完成每一个任务。
因此,让我们设置一些数据:
import numpy as np
from scipy.interpolate import interp1d
import pandas as pd
import seaborn as sns
np.random.seed(0)
N, sigma = 1000., 5
basetemps = 70 + (np.random.randn(N) * sigma)
midtemps = 50 + (np.random.randn(N) * sigma)
toptemps = 40 + (np.random.randn(N) * sigma)
alltemps = np.array([basetemps, midtemps, toptemps]).T # note transpose!
trend = np.sin(4 / N * np.arange(N)) * 30
trend = trend[:, np.newaxis]
altitudes = np.array([500, 1500, 4000]).astype(float)
finaltemps = pd.DataFrame(alltemps + trend, columns=altitudes)
finaltemps.index.names, finaltemps.columns.names = ['Time'], ['Altitude']
finaltemps.plot()
很好,所以我们的温度是这样的:
对于相同的高度,对所有时间进行插值:
我认为这一点非常简单。假设我每次都要把温度调到1000度。我可以使用内置的scipy
插值方法:
interping_function = interp1d(altitudes, finaltemps.values)
interped_to_1000 = interping_function(1000)
fig, ax = plt.subplots(1, 1, figsize=(8, 5))
finaltemps.plot(ax=ax, alpha=0.15)
ax.plot(interped_to_1000, label='Interped')
ax.legend(loc='best', title=finaltemps.columns.name)
这很好用。让我们看看速度:
%%timeit
res = interp1d(altitudes, finaltemps.values)(1000)
#-> 1000 loops, best of 3: 207 µs per loop
插入“沿路径”:
所以现在我有第二个相关的问题。假设我知道徒步旅行队的海拔高度是时间的函数,我想通过线性插值我的数据来计算他们(移动)位置的温度。特别是,我知道远足队的位置的时间是我知道我的气象站的温度的相同的时间。我不需要太多的努力就可以做到这一点:
location = np.linspace(altitudes[0], altitudes[-1], N)
interped_along_path = np.array([interp1d(altitudes, finaltemps.values[i, :])(loc)
for i, loc in enumerate(location)])
fig, ax = plt.subplots(1, 1, figsize=(8, 5))
finaltemps.plot(ax=ax, alpha=0.15)
ax.plot(interped_along_path, label='Interped')
ax.legend(loc='best', title=finaltemps.columns.name)
所以这真的很好用,但重要的是要注意到上面的关键线是使用列表理解来隐藏大量的工作。在前面的例子中,scipy
为我们创建了一个插值函数,并在大量数据上对其进行了一次评估。在这种情况下,scipy
实际上是在构造N
单独的插值函数,并在少量数据上对每个函数进行一次评估。这感觉从本质上讲是低效的。这里(在列表理解中)潜伏着一个for循环,而且,这感觉很松散。
毫不奇怪,这比前一种情况要慢得多:
%%timeit
res = np.array([interp1d(altitudes, finaltemps.values[i, :])(loc)
for i, loc in enumerate(location)])
#-> 10 loops, best of 3: 145 ms per loop
因此,第二个示例的运行速度比第一个慢1000。也就是说,与沉重的提升是“建立线性插值函数”的想法一致,step...which在第二个例子中发生了1000次,但在第一个例子中只发生了一次。
那么,问题是:有没有更好的方法来解决第二个问题?例如,有没有一个好的方法来设置它,用2-dimensinoal插值(它也许可以处理这样的情况:已知徒步旅行队位置的时间并不是采样温度的时间)?或者,有没有一种特别巧妙的方式来处理这里的事情?或者其他的?
https://stackoverflow.com/questions/33069366
复制相似问题