【问题标题】:Groupby With Multi Index具有多索引的 Groupby
【发布时间】:2016-12-08 02:30:33
【问题描述】:

我正在尝试使用 pandas 构建一个如下所示的数据框,其中 Asum 仅在那天有间隔 1 和 3 时才会获得一个值。我最接近工作的是使用这个:

 df['ASum']=df.groupby(level=['DateTime'])['A'].sum()

但是当我运行它时,它会一直返回 NaN 到 ASum。对如何做到这一点的任何想法表示赞赏。

                     A         B      ASum
DateTime   INT                                                                 
2016-07-05 3      4700.0     4700.0   0
2016-07-06 1      5906.0     6830.0   0 
           3      1090.0     1090.0   6996 
2016-07-07 1      7969.0     5273.0   0 
           3      1971.0     1971.0   9940 
2016-07-08 1      3296.0     2764.0   0
           3      1179.0     1179.0   4475 
2016-07-11 1      4993.0     5798.0   0 
           3      1325.0     1325.0   6318

【问题讨论】:

    标签: python pandas multi-index


    【解决方案1】:

    这是一个基于将INT 层级拆开、取出总和并将其堆叠回去的解决方案。

    import pandas as pd
    
    midx = pd.MultiIndex(levels=[['2016-07-05', '2016-07-06', '2016-07-07',
                                  '2016-07-08', '2016-07-11'], [1, 3]],
                         labels=[[0, 1, 1, 2, 2, 3, 3, 4, 4],
                                 [1, 0, 1, 0, 1, 0, 1, 0, 1]],
                         names=['DateTime', 'INT'])
    df = pd.DataFrame({'A': [4700.0, 5906.0, 1090.0, 7969.0, 1971.0,
                             3296.0, 1179.0, 4993.0, 1325.0],
                       'B': [4700.0, 6830.0, 1090.0, 5273.0, 1971.0,
                             2764.0, 1179.0, 5798.0, 1325.0]},
                     index=midx)
    
    df = df.unstack(level='INT')
    df[('Asum', 3)] = df['A'].sum(axis=1, skipna=False)
    df = df.stack(level='INT').fillna(0)
    print(df)
    

    输出:

                         A       B    Asum
    DateTime   INT                        
    2016-07-05 3    4700.0  4700.0     0.0
    2016-07-06 1    5906.0  6830.0     0.0
               3    1090.0  1090.0  6996.0
    2016-07-07 1    7969.0  5273.0     0.0
               3    1971.0  1971.0  9940.0
    2016-07-08 1    3296.0  2764.0     0.0
               3    1179.0  1179.0  4475.0
    2016-07-11 1    4993.0  5798.0     0.0
               3    1325.0  1325.0  6318.0
    

    【讨论】:

    • 谢谢阿尔贝托!这很好用!我一直在尝试让它与 .pct_change 一起使用,但还没有运气。
    【解决方案2】:
    df['ASum'] = 0   # the new column MUST be defined ahead
    
    for idx,data in df.groupby(level=['DateTime']):
        if all(x in data.index.get_level_values('INT') for x in [1,3]):
            df.loc[idx,'ASum'].iloc[-1] = data['A'].sum()  # adds the sum to the last row in the group only
    

    哪些结果:

                       A  ASum
    DateTime   INT            
    2016-07-05 3    4700     0
    2016-07-06 1    5906     0
               3    1090  6996
    2016-07-07 1    7967     0
               3    1971  9938
    2016-07-08 1    3296     0
               3     119  3415
    2016-07-11 1    4993     0
               3    1325  6318
    

    或者如果您希望总和出现在INT==3 的位置(不一定在最后一行):

    df['ASum'] = 0
    
    for idx,data in df.groupby(level=['DateTime']):
        if all(x in data.index.get_level_values('INT') for x in [1,3]):
            df.loc[(idx,3),'ASum'] = data['A'].sum()  # << changed this line only
    

    (直到我想出一些综合解决方案)

    【讨论】:

      猜你喜欢
      • 2021-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-17
      • 2019-02-28
      • 1970-01-01
      • 2021-12-15
      • 2018-04-17
      相关资源
      最近更新 更多