【问题标题】:Sum dataframes of different lenght, with overlapping indexes对不同长度的数据帧求和,索引重叠
【发布时间】:2019-07-18 21:31:07
【问题描述】:

我有许多相等长度和相等日期时间索引的数据帧

    Date    OPP
0   2008-01-04  0.0
1   2008-02-04  0.0
2   2008-03-04  0.0
3   2008-04-04  0.0
4   2008-05-04  0.0
5   2008-06-04  0.0
6   2008-07-04  393.75
7   2008-08-04  -168.75
8   2008-09-04  -656.25
9   2008-10-04  -1631.25


    Date    OPP
0   2008-01-04  750.0
1   2008-02-04  0.0
2   2008-03-04  150.0
3   2008-04-04  600.0
4   2008-05-04  0.0
5   2008-06-04  0.0
6   2008-07-04  0.0
7   2008-08-04  -250.0
8   2008-09-04  1000.0
9   2008-10-04  0.0

我需要创建一个独特的数据框,它将来自许多数据框的所有 OPP 列相加。这可以像这样轻松完成:

df3 = df1["OPP"] + df2["OPP"]
df3["Date"] = df1["Date"]

只要所有数据帧的长度和日期索引相同,此方法就可以工作。

即使不满足这些条件,我怎样才能使它工作?如果我有另一个这样的数据框怎么办:

        Date      OPP
0 2008-07-04   393.75
1 2008-08-04  -168.75
2 2008-09-04  -656.25
3 2008-10-04 -1631.25
4 2008-11-04  -675.00
5 2008-12-04     0.00

我可以手动执行此操作:搜索具有最小开始日期的 df,具有最大开始日期的那个,并用所有日期和零填充每个 df,这样我就有了相等长度的 df...然后进行简单的求和。

但是,有没有办法在 Pandas 中自动执行此操作?

【问题讨论】:

  • 你有多少个数据框?
  • 应该是可扩展的:最多可以达到 200 个,目前测试中只有 10 个
  • 它们现在在测试中都有正确的索引,但在生产中它们可以得到未对齐的索引,我希望它无论如何都能工作。我不想假设提供的数据具有相同的日期时间索引。

标签: python pandas dataframe


【解决方案1】:

按照this 回答方法,我们可以为此使用functools.reduce

剩下的只有sum 超过axis=1

from functools import reduce

dfs = [df1, df2, df3]

df_final = reduce(lambda left,right: pd.merge(left,right,on='Date', how='left'), dfs)

这给了我们:

         Date    OPP_x   OPP_y      OPP
0  2008-01-04     0.00   750.0      NaN
1  2008-02-04     0.00     0.0      NaN
2  2008-03-04     0.00   150.0      NaN
3  2008-04-04     0.00   600.0      NaN
4  2008-05-04     0.00     0.0      NaN
5  2008-06-04     0.00     0.0      NaN
6  2008-07-04   393.75     0.0   393.75
7  2008-08-04  -168.75  -250.0  -168.75
8  2008-09-04  -656.25  1000.0  -656.25
9  2008-10-04 -1631.25     0.0 -1631.25

然后我们求和:

df_final.iloc[:, 1:].sum(axis=1)

0     750.0
1       0.0
2     150.0
3     600.0
4       0.0
5       0.0
6     787.5
7    -587.5
8    -312.5
9   -3262.5
dtype: float64

或作为新列:

df_final['sum'] = df_final.iloc[:, 1:].sum(axis=1)

         Date    OPP_x   OPP_y      OPP     sum
0  2008-01-04     0.00   750.0      NaN   750.0
1  2008-02-04     0.00     0.0      NaN     0.0
2  2008-03-04     0.00   150.0      NaN   150.0
3  2008-04-04     0.00   600.0      NaN   600.0
4  2008-05-04     0.00     0.0      NaN     0.0
5  2008-06-04     0.00     0.0      NaN     0.0
6  2008-07-04   393.75     0.0   393.75   787.5
7  2008-08-04  -168.75  -250.0  -168.75  -587.5
8  2008-09-04  -656.25  1000.0  -656.25  -312.5
9  2008-10-04 -1631.25     0.0 -1631.25 -3262.5

【讨论】:

    【解决方案2】:

    使用列表推导式创建SeriesDatetimeIndex,然后通过concatsum 连接在一起:

    dfs = [df1, df2]
    
    compr = [x.set_index('Date')['OPP'] for x in dfs]
    df1 = pd.concat(compr, axis=1).sum(axis=1).reset_index(name='OPP')
    print (df1)
             Date      OPP
    0  2008-01-04   750.00
    1  2008-02-04     0.00
    2  2008-03-04   150.00
    3  2008-04-04   600.00
    4  2008-05-04     0.00
    5  2008-06-04     0.00
    6  2008-07-04   393.75
    7  2008-08-04  -418.75
    8  2008-09-04   343.75
    9  2008-10-04 -1631.25
    

    【讨论】:

      【解决方案3】:

      您可以简单地concat 他们和sum groupby 日期:

      (pd.concat((df1,df2,df3))
         .groupby('Date', as_index=False)
         .sum()
      )
      

      三个示例数据框的输出:

                Date     OPP
      0   2008-01-04   750.0
      1   2008-02-04     0.0
      2   2008-03-04   150.0
      3   2008-04-04   600.0
      4   2008-05-04     0.0
      5   2008-06-04     0.0
      6   2008-07-04   787.5
      7   2008-08-04  -587.5
      8   2008-09-04  -312.5
      9   2008-10-04 -3262.5
      10  2008-11-04  -675.0
      11  2008-12-04     0.0
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-11-03
        • 2017-03-18
        • 1970-01-01
        • 2018-07-27
        • 2021-07-07
        • 2023-01-13
        • 1970-01-01
        • 2016-09-07
        相关资源
        最近更新 更多