如何从Pandas DataFrame的groupby对象生成字典构成的Series
高效实现Pandas分组转换为字典Series的方法
我明白你想要的效果——把DataFrame按Col1分组,每个组里统计Col2各值的出现次数,最终生成一个以Col1为索引、对应统计字典为值的Series。你之前用循环的方法虽然能实现,但确实不够高效,尤其是数据量大的时候。
先回顾下你的进展:你已经通过my_df.groupby(['Col1','Col2']).size()得到了多级索引的计数结果,这一步是对的,接下来只需要把这个多级索引的结果按Col1聚合,转成字典就可以了。
这里有两种简洁高效的方法:
方法一:利用多级索引分组+apply转字典
这是最直接的方式,完全基于你已经得到的多级索引Series:
# 先得到每个(Col1, Col2)组合的计数 counts = my_df.groupby(['Col1', 'Col2']).size() # 按Col1(第一级索引)分组,每个组转成字典 my_series = counts.groupby(level=0).apply(lambda x: x.xs(x.name).to_dict())
解释:
groupby(level=0):按多级索引的第一级(也就是Col1)进行分组x.xs(x.name):在每个子组中,去掉当前的Col1索引,得到以Col2为索引、计数为值的Seriesto_dict():把这个Series直接转成键为Col2、值为计数的字典
方法二:用unstack后过滤转字典
另一种思路是先把多级索引的结果展开成DataFrame,再转成字典(需要过滤掉计数为0的项):
counts = my_df.groupby(['Col1', 'Col2']).size() # 展开成DataFrame,缺失的项填充0 unstacked = counts.unstack(fill_value=0) # 对每一行(每个Col1),过滤掉值为0的项并转字典 my_series = unstacked.apply(lambda row: row[row > 0].to_dict(), axis=1)
效果验证
用你的示例数据测试:
import pandas as pd # 构造示例DataFrame data = { 'Col1': ['A', 'B', 'A', 'C', 'A', 'B', 'A', 'B'], 'Col2': ['b', 'e', 'a', 'a', 'b', 'c', 'e', 'c'] } my_df = pd.DataFrame(data) # 执行方法一的代码 counts = my_df.groupby(['Col1', 'Col2']).size() my_series = counts.groupby(level=0).apply(lambda x: x.xs(x.name).to_dict())
得到的my_series就是你想要的结果:
A {'a': 1, 'b': 2, 'e': 1} B {'c': 2, 'e': 1} C {'a': 1} dtype: object
这两种方法都避免了手动循环,利用Pandas的内置优化操作,效率比循环高很多,尤其是处理大数据集的时候优势更明显。
内容的提问来源于stack exchange,提问作者Danilo
相关产品推荐
相关产品推荐

