如何将数据集月日格式转为datetime并索引以绘制双Y轴图表
解决Datestamp格式转换与双Y轴图表绘制问题
核心需求
- 绘制5组双Y轴图表:每组X轴为日期,Y轴分别对应Ontario和CMB的同序号列(如Ontario第2列 vs CMB第2列)
- 数据问题:两个数据集的
Datestamp列为mm-dd格式的object类型,日期不完全一致;需转为datetime类型,规则为:月份是12则年份设为2022,月份是1则年份设为2023(后续可按需切换年份规则)
日期转换正确方案
方法1:自定义函数批量转换(易读性高)
import pandas as pd def fix_datestamp(date_str): # 先解析mm-dd为datetime(默认年份会取当前年,后续替换) dt_obj = pd.to_datetime(date_str, format='%m-%d') # 根据月份替换年份 if dt_obj.month == 12: dt_obj = dt_obj.replace(year=2022) elif dt_obj.month == 1: dt_obj = dt_obj.replace(year=2023) # 其他月份可按需扩展规则 return dt_obj # 对两个数据集应用转换 dfplot_ont['Datestamp'] = dfplot_ont['Datestamp'].apply(fix_datestamp) dfplot_cmb['Datestamp'] = dfplot_cmb['Datestamp'].apply(fix_datestamp)
方法2:矢量化操作(效率更高,适合大数据集)
import pandas as pd # 处理Ontario数据集 dfplot_ont['Datestamp'] = pd.to_datetime(dfplot_ont['Datestamp'], format='%m-%d') # 替换12月的年份为2022 mask_dec = dfplot_ont['Datestamp'].dt.month == 12 dfplot_ont.loc[mask_dec, 'Datestamp'] = dfplot_ont.loc[mask_dec, 'Datestamp'].apply(lambda x: x.replace(year=2022)) # 替换1月的年份为2023 mask_jan = dfplot_ont['Datestamp'].dt.month == 1 dfplot_ont.loc[mask_jan, 'Datestamp'] = dfplot_ont.loc[mask_jan, 'Datestamp'].apply(lambda x: x.replace(year=2023)) # 对CMB数据集执行同样操作 dfplot_cmb['Datestamp'] = pd.to_datetime(dfplot_cmb['Datestamp'], format='%m-%d') mask_dec_cmb = dfplot_cmb['Datestamp'].dt.month == 12 dfplot_cmb.loc[mask_dec_cmb, 'Datestamp'] = dfplot_cmb.loc[mask_dec_cmb, 'Datestamp'].apply(lambda x: x.replace(year=2022)) mask_jan_cmb = dfplot_cmb['Datestamp'].dt.month == 1 dfplot_cmb.loc[mask_jan_cmb, 'Datestamp'] = dfplot_cmb.loc[mask_jan_cmb, 'Datestamp'].apply(lambda x: x.replace(year=2023))
之前尝试方法的问题分析
- 方法1中使用
dt.strftime('%m-%d')会把转换后的datetime对象转回字符串,导致Datestamp仍为object类型,未达到转datetime的目的。 - 方法2的格式字符串写错:
%MM-%dd是错误写法,正确的月份格式为%m,应改为pd.to_datetime(dfplot_ont['Datestamp'], format='%m-%d')。 - 方法3的格式字符串错误:
%M代表分钟而非月份,正确的月份格式是%m,导致日期解析完全错误。
双Y轴图表绘制示例(Matplotlib)
假设数据集的同序号列对应要对比的指标,示例代码如下:
import matplotlib.pyplot as plt # 遍历5组对比列(根据实际列索引/列名调整范围) for idx in range(1, 6): ont_col = dfplot_ont.columns[idx] cmb_col = dfplot_cmb.columns[idx] # 创建画布与左侧Y轴 fig, ax1 = plt.subplots(figsize=(10, 6)) # 绘制Ontario数据 ax1.plot(dfplot_ont['Datestamp'], dfplot_ont[ont_col], color='tab:blue', label=f'Ontario {idx}') ax1.set_xlabel('日期') ax1.set_ylabel(f'Ontario {idx}', color='tab:blue') ax1.tick_params(axis='y', labelcolor='tab:blue') # 创建右侧Y轴并绘制CMB数据 ax2 = ax1.twinx() ax2.plot(dfplot_cmb['Datestamp'], dfplot_cmb[cmb_col], color='tab:orange', label=f'CMB {idx}') ax2.set_ylabel(f'CMB {idx}', color='tab:orange') ax2.tick_params(axis='y', labelcolor='tab:orange') # 合并图例 lines1, labels1 = ax1.get_legend_handles_labels() lines2, labels2 = ax2.get_legend_handles_labels() ax1.legend(lines1 + lines2, labels1 + labels2, loc='upper left') # 美化图表 plt.title(f'Ontario {idx} vs CMB {idx}') plt.xticks(rotation=45) plt.tight_layout() plt.show()
内容的提问来源于stack exchange,提问作者rrb
相关产品推荐
相关产品推荐

