查看上次编辑
您可以将interp1d 函数应用于每一行:
df['YInt'] = df.apply(lambda row:
interp1d([row.X1, row.X2],
[row.Y1, row.Y2],
bounds_error=False
)(row.X),
axis=1)
但这在大型数据帧上相当慢,但我不确定如何优化它。
编辑:
很难优化,因为您必须进行逐行操作。您应该查看 Pandas 文档中的 Enhancing Performance Guide 以获得更多信息。但无论如何,使用numba,我设法通过类似于我之前给出的方法将性能提高了 4 倍:
@numba.vectorize([numba.float64(numba.float64, # Return type is float
numba.float64, # with 5 float arguments
numba.float64,
numba.float64,
numba.float64)])
def interp_helper_numba(x1, x2, y1, y2, x):
return interp1d([x1, x2], [y1, y2], bounds_error=False)(x)
df['Y'] = interp_helper_numba(df.X1.values, df.X2.values,
df.Y1.values, df.Y2.values,
df.X.values)
Pandas 本身也有包装 scipy.interpolate.interp1d 的 pd.Series.interpolate 函数,但如果你想使用它,你会遇到同样的问题:你想逐行插值。
编辑:
由于这只是正常的两点线性插值,因此可以很容易地手动计算这些值:
def manual_interp(x1, x2, y1, y2, x):
return (y1 * (x2 - x) + y2 * (x - x1)) / (x2 - x1)
df['Y'] = manual_interp(df.X1.values, df.X2.values,
df.Y1.values, df.Y2.values,
df.X.values)
在具有 1 亿行的数据集上对其进行了测试,并在一秒钟内完成。 :)
最后的编辑,因为 Rolo 想要一个单线:
df['Y'] = (df.Y1.values * (df.X2.values - df.X.values) + df.Y2.values * (df.X.values - df.X1.values)) / (df.X2.values - df.X1.values)