如何高效聚合多列生成指定格式的分组统计DataFrame?
如何高效聚合多列生成指定格式的分组统计DataFrame?
嘿,你的思路已经找对方向啦!循环处理目标列的方式完全可行,只需要在循环里把每个分组后的结果调整成你想要的格式,再把所有子结果合并起来就搞定了。下面给你两种清晰高效的实现方法:
方法一:循环处理 + 批量合并(最贴合你的现有代码)
你已经能拿到每个分组的统计结果,只需要补充列名调整和结果收集合并的步骤就行,具体如下:
import pandas as pd # 你的原始数据 data = {'ID': [105, 106, 107, 108, 109, 110, 111, 112], 'Name': ['Bill', 'Jane', 'Mary', 'Rich', 'Tomas', 'Kiki', 'Martin', 'Larry'], 'Cohort': ['Cohort A', 'Cohort A', 'Cohort A', 'Cohort A', 'Cohort B', 'Cohort B', 'Cohort B', 'Cohort B'], 'Program Size': ['small', 'large', 'medium', 'medium', 'large', 'small', 'large', 'medium'], 'Rating': ['excellent', 'good', 'needs improvement', 'needs improvement', 'good', 'excellent', 'good', 'excellent']} df = pd.DataFrame(data) # 定义目标列和对应的Variable值映射 cols = ['Program Size', 'Rating'] col_to_variable = {'Program Size': 'size', 'Rating': 'rating'} # 初始化空列表,用于存储每个分组后的格式化子DataFrame result_list = [] for col in cols: # 按Cohort和当前列分组统计频率(和你原来的代码逻辑一致) grouped = df.groupby(['Cohort', col], as_index=False).agg(Frequency=('ID', 'count')) # 重命名分组列为Description,并添加Variable列 grouped = grouped.rename(columns={col: 'Description'}) grouped['Variable'] = col_to_variable[col] # 调整列的顺序,和目标格式完全对齐 grouped = grouped[['Cohort', 'Variable', 'Description', 'Frequency']] # 将当前子结果加入列表 result_list.append(grouped) # 合并所有子DataFrame,重置索引 final_df = pd.concat(result_list, ignore_index=True) print(final_df)
运行后得到的结果完全和你想要的desired_df一致,每一步的作用我都加了注释,你可以跟着代码逻辑一步步对应到你的需求。
方法二:先转长格式再分组(更简洁的进阶写法)
如果你想尝试更紧凑的写法,可以先把数据转成长格式,再一次性完成分组统计,代码会更简洁:
import pandas as pd # 原始数据同上,省略重复代码 df = pd.DataFrame(data) # 先把Program Size和Rating转成长格式,直接生成Variable和Description列 melted_df = df.melt( id_vars=['Cohort', 'ID'], value_vars=['Program Size', 'Rating'], var_name='Variable', value_name='Description' ) # 替换Variable列的名称为你需要的简写 melted_df['Variable'] = melted_df['Variable'].map({'Program Size': 'size', 'Rating': 'rating'}) # 按Cohort、Variable、Description分组统计频率 final_df = melted_df.groupby(['Cohort', 'Variable', 'Description'], as_index=False).agg(Frequency=('ID', 'count')) # 调整列顺序并重置索引 final_df = final_df[['Cohort', 'Variable', 'Description', 'Frequency']].reset_index(drop=True) print(final_df)
这种方法利用melt把宽表转成符合你需求的长表结构,再一次分组就完成了统计,代码行数更少,适合目标列数量较多的场景。
两种方法都能高效得到你想要的结果,你可以根据自己的习惯选择~
备注:内容来源于stack exchange,提问作者user29747013
相关产品推荐
相关产品推荐

