【问题标题】:Row-wise Interpolation in dataframe using interp1d使用 interp1d 在数据帧中进行逐行插值
【发布时间】:2018-05-15 15:36:01
【问题描述】:

我在 python 中有以下数据框(df):

X1  X2  Y1  Y2  X   YInt
10  20  0.6 1   17  ???
5   50  0.4 1   9   ???

我正在尝试向该数据帧添加一个新列 (YInt),它会评估给定 X 和给定行中给定坐标 X1、Y2、X2、Y2 的线性插值 Y 值。

到目前为止,我有以下代码:

df['YInt'] = interp1d(df[['X1','X2']],df[['Y1','Y2']],bounds_error=False)(df['X'])

但是会报错,Arrays不等长。

【问题讨论】:

    标签: python pandas scipy interpolation


    【解决方案1】:

    查看上次编辑

    您可以将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.interp1dpd.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)
    

    【讨论】:

    • 谢谢。不幸的是,我的 df 相当大,因此这种方式相当慢。有没有办法加快计算速度?
    • 谢谢 Jurgy,插值计算很简单,你说得对。但是,我仍然希望找到一种不会遍历每一行的单行代码解决方案。 np.interp / interp1d / pd.interpolate 似乎都没有做这项工作,或者我还没有找到方法。
    • @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) 但在我看来可读性较差,但如果这是您想要的,请成为我的客人;)由于您是 SO 新手,请标记我的如果满意,则回答为“已回答”。
    • 感谢 Jurgy!我认为最新版本可能是我将使用的版本。即使它不是最易读的。
    猜你喜欢
    • 2019-05-18
    • 1970-01-01
    • 2022-01-13
    • 2016-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-23
    • 1970-01-01
    相关资源
    最近更新 更多