如何基于分组value_counts结果绘制多折线图并转换为宽格式?
问题
执行以下Python代码:
df.groupby('arrival_date_year').market_segment.value_counts()
得到如下分组计数结果:
arrival_date_year market_segment 2015 Online TA 6165 Groups 6100 Offline TA/TO 6079 Direct 2314 Corporate 1171 Complementary 165 Undefined 2 2016 Online TA 27661 Offline TA/TO 12473 Groups 7857 Direct 5663 Corporate 2562 Complementary 364 Aviation 127 2017 Online TA 22651 Groups 5854 Offline TA/TO 5667 Direct 4629 Corporate 1562 Complementary 214 Aviation 110
提出两个问题:
- 如何编写正确语法,绘制以年份为X轴、计数值为Y轴,代表各
market_segment的多折线图? - 如何将数据转换为宽格式以便更直观地对比各组计数?
解答
1. 绘制多折线图
先将分组计数结果转换为适合绘图的结构,再用matplotlib或seaborn实现多折线图:
方法一:使用Seaborn
import matplotlib.pyplot as plt import seaborn as sns # 把多级索引的Series转为带列名的DataFrame counts = df.groupby('arrival_date_year').market_segment.value_counts().reset_index(name='count') # 绘制多折线图 plt.figure(figsize=(10, 6)) sns.lineplot(data=counts, x='arrival_date_year', y='count', hue='market_segment', marker='o') plt.title('各市场细分年度计数趋势') plt.xlabel('年份') plt.ylabel('计数') plt.legend(title='市场细分', bbox_to_anchor=(1.05, 1), loc='upper left') plt.tight_layout() plt.show()
方法二:使用Matplotlib直接绘制
import matplotlib.pyplot as plt # 先转宽格式再绘图 counts_wide = df.groupby('arrival_date_year').market_segment.value_counts().unstack(fill_value=0) counts_wide.plot(kind='line', marker='o', figsize=(10, 6)) plt.title('各市场细分年度计数趋势') plt.xlabel('年份') plt.ylabel('计数') plt.legend(title='市场细分', bbox_to_anchor=(1.05, 1), loc='upper left') plt.tight_layout() plt.show()
2. 转换为宽格式
利用unstack()方法快速将多级索引的分组结果转为宽格式,便于对比:
# 转换为宽格式,缺失值用0填充 wide_format_df = df.groupby('arrival_date_year').market_segment.value_counts().unstack(fill_value=0) # 查看转换结果 print(wide_format_df)
转换后的输出格式如下:
market_segment Aviation Complementary Corporate Direct Groups Offline TA/TO Online TA Undefined arrival_date_year 2015 0 165 1171 2314 6100 6079 6165 2 2016 127 364 2562 5663 7857 12473 27661 0 2017 110 214 1562 4629 5854 5667 22651 0
如果需要通过pivot实现,可先将结果转为常规DataFrame再操作:
counts_df = df.groupby('arrival_date_year').market_segment.value_counts().reset_index(name='count') wide_format_df = counts_df.pivot(index='arrival_date_year', columns='market_segment', values='count').fillna(0)
内容的提问来源于stack exchange,提问作者sanket patel
相关产品推荐
相关产品推荐

