如何将含日期列头的宽表数据按id和period分组绘制折线图
解决方案
你的处理思路完全正确,宽表转长表(逆透视)是这类时间序列分组统计、可视化场景的标准最优解法,不需要手动处理,pandas内置的melt方法一行即可完成转换。
1. 宽表转长表代码
# id_vars指定要保留的非日期列,var_name指定存储原列名(日期)的字段名,value_name指定存储数值的字段名 df_long = df.melt( id_vars = ['id', 'period'], var_name = 'date', value_name = 'value' )
转换后得到4列结构的长表:id、period、date、value,完全符合你的后续处理需求。
2. 直接绘制分组折线图
转换完成后不需要额外做groupby操作,直接用seaborn或者matplotlib绘图即可,示例如下:
import seaborn as sns import matplotlib.pyplot as plt plt.figure(figsize=(10, 6)) # 用hue同时按id和period分组,自动生成6条折线 sns.lineplot( data = df_long, x = 'date', y = 'value', hue = df_long['id'] + '_' + df_long['period'], marker = 'o' ) plt.xlabel('日期') plt.ylabel('数值') plt.legend(title = '分组(id_period)') plt.show()
如果要使用原生matplotlib分组绘图,也可以直接遍历groupby结果:
plt.figure(figsize=(10, 6)) for (id_val, period_val), group_df in df_long.groupby(['id', 'period']): plt.plot(group_df['date'], group_df['value'], marker='o', label=f'{id_val}_{period_val}') plt.xlabel('日期') plt.ylabel('数值') plt.legend(title = '分组(id_period)') plt.show()
内容的提问来源于stack exchange,提问作者Denver Dang
相关产品推荐
相关产品推荐

