我有以下python中的dataframe (df):
X1 X2 Y1 Y2 X YInt
10 20 0.6 1 17 ???
5 50 0.4 1 9 ???我试图在该数据中添加一个新列(YInt),它计算给定X的线性插值Y值和给定行中的给定坐标X1、Y2、X2、Y2。
到目前为止,我有以下代码:
df['YInt'] = interp1d(df[['X1','X2']],df[['Y1','Y2']],bounds_error=False)(df['X'])但是,报告了一个错误,即数组的长度不相等。
发布于 2017-12-01 14:14:48
见最后一次编辑
您可以将interp1d函数应用于每一行:
df['YInt'] = df.apply(lambda row:
interp1d([row.X1, row.X2],
[row.Y1, row.Y2],
bounds_error=False
)(row.X),
axis=1)但是对于大型数据文件来说,这是相当慢的,但我不知道如何优化它。
编辑:
很难进行优化,因为您必须执行逐行操作。您应该查看Pandas文档中的增强业绩指南,以获得更多的洞察力。但是无论如何,使用南巴,我成功地获得了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)熊猫还拥有包装pd.Series.interpolate的scipy.interpolate.interp1d函数本身,但是如果你想使用它,你会遇到同样的问题:你想按行插值。
编辑:
由于这只是普通的两点线性插值,因此可以很容易地手工计算这些值:
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亿行的dataset上测试它,并在一秒钟内完成。:)
最后编辑,因为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)https://stackoverflow.com/questions/47594932
复制相似问题