按多列分组时熊猫组合键

Posted

技术标签:

【中文标题】按多列分组时熊猫组合键【英文标题】: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
                         
                 
         

我该怎么做?

【问题讨论】:

【参考方案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() 虽然有效。

以上是关于按多列分组时熊猫组合键的主要内容,如果未能解决你的问题,请参考以下文章

数据库演练外键SQL语句的编写&分组和聚合函数的组合使用

如何按多列分组以在熊猫数据框中列出

按多列分组并将dict元素的中值作为熊猫中的新列

mysql 慢查询分析

Win+Break”组合键 怎么打?

如何取消开机按ctrl+alt+delete组合键