pandas如何通过groupby简化分组分布统计并绘制并列柱状图
问题说明
需要实现各region分组下label列的数值分布统计与绘图,原有方案通过生成哑变量、逐组创建透视表、循环拼接新DataFrame实现,流程繁琐,需要更简洁的统计实现逻辑(如基于groupby的高级用法),同时需要明确并列柱状图的调整方法。
测试数据生成代码
可运行以下代码复现测试用DataFrame:
import pandas as pd import numpy as np np.random.seed(1) a = np.random.choice(['region_A', 'region_B', 'region_C', 'region_D', 'region_E'], size=30, p= [0.1, 0.2, 0.3, 0.30, 0.1]) b = np.random.choice(['1', '0'], size=30, p=[0.5, 0.5]) df = pd.DataFrame({'region': a, 'label': b})
原有繁琐实现
原有实现代码如下,存在冗余的哑变量生成、循环拼接逻辑:
dummy = pd.get_dummies(df['region']) region_lst = [] label_0 = [] label_1 = [] for col in dummy.columns: region_lst.append(col) label_0.append(pd.crosstab(dummy[col], df['label']).iloc[1,0]) label_1.append(pd.crosstab(dummy[col], df['label']).iloc[1,1]) df_labels = pd.DataFrame({'label_0': label_0, 'label_1': label_1}, index=region_lst) df_labels.plot.bar()
简洁实现方案
统计逻辑简化
不需要生成哑变量、写循环拼接,以下两种一行写法都可以直接得到和原有逻辑完全一致的统计结果:
- 方法1:直接用
pd.crosstab做分组列联统计,是最适配这个场景的写法df_labels = pd.crosstab(index=df['region'], columns=df['label']) # 可选:重命名列和原有代码保持一致 df_labels.columns = [f'label_{c}' for c in df_labels.columns] - 方法2:用
groupby配合unstack实现,符合用groupby简化逻辑的需求df_labels = df.groupby(['region', 'label']).size().unstack(fill_value=0) df_labels.columns = [f'label_{c}' for c in df_labels.columns]
柱状图类型调整
pandas 自带的plot.bar()方法默认参数stacked=False,直接调用就是并列柱状图效果,不需要额外传参:
# 绘制并列柱状图,rot=0是让x轴标签水平显示,可按需调整 df_labels.plot.bar(rot=0)
如果需要切换为堆叠柱状图,只需要传入stacked=True参数即可:
# 堆叠柱状图写法 df_labels.plot.bar(stacked=True, rot=0)
内容的提问来源于stack exchange,提问作者user10969675
相关产品推荐
相关产品推荐

