【问题标题】:Pandas combining keys when grouping by multiple column按多列分组时熊猫组合键
【发布时间】:2016-12-06 07:30:33
【问题描述】:

我有 3 个基于 3 个键的分组级别:key1、key2、key3 我想获得以下组合的列 (c1) 的总和:

key1, sum(c1)
key1, key2, sum(c1)
key1, key2, key3, sum(c1)

我在 3 个不同的 dfs 中得到总和。 (sum_k1, sum_k1k2, sum_k1k2k3) 我想组合数据框,然后将其转换为 json,如下所示:

{
 key1: { 
          sum: x1,
          key2: {
                   sum: x2,
                   key3: {
                           sum: x3
                         }
                 }
         }
}

我该怎么做?

【问题讨论】:

    标签: python json pandas numpy


    【解决方案1】:

    我为此使用了多级索引,为此使用了 xs。 获取最低级别的聚合。

    lvl3_grp = df.groupby(['key1', 'key2', 'key3'])['col1', 'col2'].sum()
    lvl3_grp = lvl3_grp.reset_index()
    lvl3_grp.set_index(['key1', 'key2', 'key3'], inplace=True)
    
    res = {}
    for k1 in lvl3_grp.index.levels[0]:
     sums = lvl3_grp.xs(k1).sum()
     lvl2_grp = lvl3_grp.xs(k1).reset_index()
     lvl2_grp.set_index(['key2', 'key3'], inplace=True)
     lvl2_dict = {}
     for k2 in lvl2_grp.index.levels[0]:
       sums = lvl2_grp.xs(k1).sum()
    

    最后一级.index.levels[0] 不能作为其单一索引。我使用.index.values 用于可迭代列表,并在for 循环中使用.loc 来访问值。

    稍后我会扩展答案。

    【讨论】:

      【解决方案2】:

      我不知道这是否是最有效的方法,但这是我想出的

      import pandas as pd
      import random
      
      # Prepare the sample dataset
      
      table = []
      for i in range(100000):
          row = {'key1': random.choice('ABC'),
                 'key2': random.choice('KLM'),
                 'key3': random.choice('XYZ'),
                 'val' : random.randint(0,500)}
          table.append(row)
      
      df = pd.DataFrame(table)
      
      # Aggregate the first level
      
      dict_agg = (df.groupby('key1')
                  .sum()
                  .rename(columns={'val':'sum'})
                  .to_dict('index'))
      
      # Convert from numpy.int64 to Python scalar
      for idx, value in dict_agg.items():
          dict_agg[idx]['sum'] = int(dict_agg[idx]['sum'])
      
      # Aggregate the second level
      
      df_lvl2 = (df.groupby(['key1','key2'])
                 .sum()
                 .rename(columns={'val':'sum'})
                 .to_dict('index'))
      
      # Assign the second level aggregation
      
      for idx, value in df_lvl2.items():
          dict_agg[idx[0]][idx[1]] = {'sum': int(value['sum'])}
      
      # Aggregate the final level
      
      df_lvl3 = (df.groupby(['key1','key2','key3'])
                 .sum()
                 .rename(columns={'val':'sum'})
                 .to_dict('index'))
      
      # Assign the third level aggregation
      
      for idx, value in df_lvl3.items():
          dict_agg[idx[0]][idx[1]][idx[2]] = {'sum': int(value['sum'])}
      

      最终结果将如下所示:

      {'A': {'K': {'X': {'sum': 929178},
         'Y': {'sum': 940925},
         'Z': {'sum': 938008},
         'sum': 2808111},
        'L': {'X': {'sum': 902581},
         'Y': {'sum': 953821},
         'Z': {'sum': 942942},
         'sum': 2799344},
        'M': {'X': {'sum': 930117},
         'Y': {'sum': 929257},
         'Z': {'sum': 910905},
         'sum': 2770279},
        'sum': 8377734},
       'B': {'K': {'X': {'sum': 888818},
      …
      

      由于这是一个dict,您需要将其转换为 json,方法是:

      import json
      output = json.dumps(dict_agg)
      

      【讨论】:

      • 因为我有多个列要求和。在总和部分,我正在这样做。第一级:df.groupby('key1')['col1'].sum()。 to_dict('index') 失败。
      • 。重命名位失败。 to_dict('index') 也失败了。 .to_dict() 虽然有效。
      猜你喜欢
      • 1970-01-01
      • 2021-05-13
      • 2020-07-09
      • 2021-05-07
      • 2018-12-29
      • 2017-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多