You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python调整柱状图时间并补全缺失月度的零值

月度频率柱状图零值月份缺失问题排查与修复

问题背景

现有一组含缺失值的YEAR、MONTH数据,需绘制1960-2020年的月度频率柱状图,但运行指定Python代码后,本该显示零值的月份(如二月)未出现在图表中,需排查代码问题并调整以正确展示所有月份的频率(含零值)。

原始数据

YEAR    MONTH
1960    5
1961    7
1961    8
1961    11
1962    5
1963    6
1964    
1965    7
1966    7
1966    7
1966    10
1967    4
1967    8
1968    
1969    
1970    8
1971    6
1971    9
1971    10
1972    7
1973    6
1973    9
1974    10
1974    10
1975    10
1976    
1977    
1978    9
1979    11
1980    7
1980    7
1980    8
1981    
1982    10
1982    12
1983    
1984    7
1985    9
1986    
1987    
1988    9
1988    10
1989    7
1989    10
1990    
1991    7
1992    
1993    6
1993    7
1993    9
1993    9
1994    
1995    7
1996    8
1996    9
1997    5
1998    8
1998    9
1998    10
1999    8
1999    9
2000    9
2001    
2002    1
2003    5
2003    7
2003    8
2003    9
2003    10
2004    
2005    11
2006    7
2006    10
2007    9
2007    11
2007    11
2008    5
2009    5
2009    7
2009    9
2009    9
2010    10
2011    5
2011    9
2011    9
2012    8
2013    7
2014    9
2015    7
2016    
2017    8
2018    10
2019    11
2020    

原始代码

#Plot Frequency
ISA = pd.read_csv (r'G\:data.csv', encoding="ISO-8859-1")
ISA = pd.DataFrame(ISA,columns=['YEAR','MONTH','TYPE'])
ISA=  ISA[ISA['YEAR'].between(1960,2020, inclusive="both")]
ISA['YEAR'] = pd.to_datetime(ISA['MONTH'])
ISA = ISA.set_index('YEAR')
ISA=ISA.drop(['MSW','TC NAME', 'KNOTS','PAR BEG', 'PAR END'],axis=1)
ISA=ISA.dropna(axis=0, how='any', thresh=None, subset=None, inplace=False)
ax=ISA.groupby([ISA.index.month, 'MONTH']).count().plot(kind='bar',color='lightgray',width=1, edgecolor='darkgray')
plt.xlabel('Month', color='black', fontsize=14, weight='bold')
plt.ylabel('Monthly frequency' , color='black', fontsize=14, weight='bold',)
plt.xticks([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct','Nov','Dec'],rotation=0, fontsize=12)
ax.yaxis.set_major_formatter(FormatStrFormatter('%.0f'))
plt.yticks(fontsize=12)
plt.ylim(0,20)
plt.suptitle("Monthly Frequency",fontweight='bold',y=0.95,x=0.53)
plt.title("ISA", pad=0)
L=plt.legend()
L.get_texts()[0].set_text('Frequency')
plt.bar_label(ax.containers[0], label_type='center', fontsize=11)
plt.plot()
plt.tight_layout()
plt.show()

问题排查

  • YEAR列被错误覆盖:代码中ISA['YEAR'] = pd.to_datetime(ISA['MONTH'])直接用月份生成的日期替换了原始年份数据,完全丢失年份信息,导致后续分组逻辑混乱。
  • 过度删除缺失值:ISA=ISA.dropna(axis=0, how='any')删除了所有含缺失值的行,包括仅MONTH缺失的年份数据,使得这些年份的所有月份都无法参与统计。
  • 分组逻辑冗余且不完整:groupby([ISA.index.month, 'MONTH'])重复按月份分组,且未确保包含1-12所有月份,无数据的月份被自动忽略。
  • 刻度映射不匹配:手动设置12个月份的刻度,但实际分组结果只有有数据的月份,导致刻度与柱子对应关系错误。

修正后的代码

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.ticker import FormatStrFormatter

# 读取数据
ISA = pd.read_csv(r'G:\data.csv', encoding="ISO-8859-1")
# 仅保留需要的列
ISA = ISA[['YEAR', 'MONTH']]
# 筛选1960-2020年的数据
ISA = ISA[ISA['YEAR'].between(1960, 2020, inclusive="both")]
# 仅删除MONTH为空的行(无月份的行无法归类到具体月度)
ISA = ISA.dropna(subset=['MONTH'])
# 将MONTH转为整数类型
ISA['MONTH'] = ISA['MONTH'].astype(int)

# 生成1-12月的完整月份序列
full_months = pd.DataFrame({'MONTH': range(1, 13)})
# 按MONTH分组统计频率,合并完整月份序列并填充零值
monthly_counts = ISA.groupby('MONTH').size().reset_index(name='Frequency')
monthly_counts = pd.merge(full_months, monthly_counts, on='MONTH', how='left').fillna(0)

# 绘制柱状图
plt.figure(figsize=(10,6))
ax = monthly_counts.plot(kind='bar', x='MONTH', y='Frequency', color='lightgray', width=1, edgecolor='darkgray', legend=False)

# 设置图表样式
plt.xlabel('Month', color='black', fontsize=14, weight='bold')
plt.ylabel('Monthly frequency', color='black', fontsize=14, weight='bold')
# 设置x轴刻度为月份名称
plt.xticks(range(12), ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct','Nov','Dec'], rotation=0, fontsize=12)
# y轴显示整数
ax.yaxis.set_major_formatter(FormatStrFormatter('%.0f'))
plt.yticks(fontsize=12)
plt.ylim(0,20)
plt.suptitle("Monthly Frequency", fontweight='bold', y=0.95)
plt.title("ISA", pad=10)
# 添加柱子中心标签
plt.bar_label(ax.containers[0], label_type='center', fontsize=11)

plt.tight_layout()
plt.show()

代码说明

  1. 保留原始YEAR列,仅针对性删除MONTH为空的行,确保年份筛选逻辑正确。
  2. 生成1-12月的完整序列,通过merge合并统计结果,自动填充无数据月份的频率为0,保证所有月份都出现在图表中。
  3. 简化分组逻辑,直接按MONTH分组统计数量,避免索引混乱。
  4. 移除冗余的列删除和重复分组操作,代码逻辑更清晰。

内容的提问来源于stack exchange,提问作者user2543

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 10:55:16