【问题标题】:How to Interpolate between all Values in Two Separate Pandas DataFrames?如何在两个单独的 Pandas DataFrame 中的所有值之间进行插值?
【发布时间】:2019-06-29 13:03:55
【问题描述】:

假设您有两个 Pandas DataFrame,一个包含 2020 年的数据,另一个包含 2030 年的数据。两个 DataFrame 具有相同的形状、列名,并且只包含数值。为简单起见,我们将按如下方式创建它们:

twenty = pd.DataFrame({'A':[1,1,1], 'B':[3,3,3]})
thirty = pd.DataFrame({'A':[3,3,3], 'B':[7,7,7]})

现在,目标是对这些 DataFrame 中的所有值执行线性插值,以获得 2025 年(或我们选择的任何年份)的新 DataFrame。因此,我们希望在每对值集之间进行插值,例如twenty['A'][0]thirty['A'][0]。如果我们在 2025 年的目标年这样做,结果应该是:

twentyfive = pd.DataFrame({'A':[2,2,2],'B':[5,5,5]})

我尝试使用np.interp;但是,据我所知,这实际上是用于对给定(奇异)数组进行插值。我已经解决了这个问题,使用一种更暴力的方法来融合 DataFrame,添加年份列,将它们合并在一起,然后使用插值创建一个新列。它有点凌乱和冗长。

我觉得必须有一种更直接(和优化)的方式来执行这项任务。任何帮助表示赞赏。

【问题讨论】:

    标签: python pandas interpolation


    【解决方案1】:

    如果两者形状相同,可以尝试直接取平均值

    (thirty + twenty)/2
    

    输出:

        A   B
    0   2   5
    1   2   5
    2   2   5
    

    编辑:如果数据框的形状不相等,您可以尝试与内部连接和 groupby 列合并以获取插值。

    df = pd.merge(twenty,thirty, left_index=True, right_index=True, how='inner').rename(columns=lambda x: x.split('_')[0])
    df.T.groupby(df.T.index).mean().T
    

    输出:

        A   B
    0   2   5
    1   2   5
    2   2   5
    

    【讨论】:

    • 啊,好点子。我不确定我是否曾经想过你可以将 DataFrame 加、减等放在一起,如果它们具有相同的形状;但是,这是有道理的。而且,为了更一般地用于线性插值,您可以将添加的 DataFrames 乘以 (target-2020) / (2030-2020),而不是除以 2(在本例中为 2025)。
    • 是的,如果您有少量DataFrames 并且需要简单的线性插值,这可能是最好的方法。如果您有很多 DataFrames 并且需要计算哪两个需要用于给定年份的平均值,则可能会更加困难。
    【解决方案2】:

    您可以 concat 对键进行智能处理(将它们命名为整数),然后 groupby 允许您对所有内容进行插值:

    import pandas as pd
    
    df = pd.concat([twenty, thirty], keys=[20,30], axis=1)
    s = (df.groupby(df.columns.get_level_values(1), axis=1)
            .apply(lambda x: x.T.reset_index(1, drop=True).reindex(np.arange(20,31)).interpolate())).T
    
          20   21   22   23   24   25   26   27   28   29   30
    A 0  1.0  1.2  1.4  1.6  1.8  2.0  2.2  2.4  2.6  2.8  3.0
      1  1.0  1.2  1.4  1.6  1.8  2.0  2.2  2.4  2.6  2.8  3.0
      2  1.0  1.2  1.4  1.6  1.8  2.0  2.2  2.4  2.6  2.8  3.0
    B 0  3.0  3.4  3.8  4.2  4.6  5.0  5.4  5.8  6.2  6.6  7.0
      1  3.0  3.4  3.8  4.2  4.6  5.0  5.4  5.8  6.2  6.6  7.0
      2  3.0  3.4  3.8  4.2  4.6  5.0  5.4  5.8  6.2  6.6  7.0
    

    现在,如果您只关心 25:

    s[25].unstack(0)
    
         A    B
    0  2.0  5.0
    1  2.0  5.0
    2  2.0  5.0
    

    【讨论】:

    • 非常聪明!它可以让你一次性度过所有的过渡时期。好主意。
    • 尽管考虑到所有 groupby 重新索引,它可能会相当慢,并且插值很慢。但是,如果您有其他帧,例如 33、39、59、97,它会很容易扩展。只需使用适当的键添加它们并立即获取所有内容。
    猜你喜欢
    • 1970-01-01
    • 2015-10-15
    • 2023-02-21
    • 2023-03-24
    • 2018-06-27
    • 1970-01-01
    • 2021-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多