Pandas统计不同微生物月出现次数及for循环KeyError报错解决
代码错误原因
- 循环逻辑错误:
for row in ssidf.1_TYPE遍历得到的是1_TYPE列的实际值(比如Gram Neg、Fungi这类字符串),并非行索引,后续用ssidf.1_TYPE[row]相当于用字符串作为索引取值,自然触发KeyError。 - 赋值符号错误:代码里用了
==判断相等的符号做赋值操作,实际上=才是赋值符号,你的原有代码没有给任何新列赋值。 - 方法调用错误:
str.contains是Pandas Series(列)的方法,不能作用在单个字符串元素上,单元素判断直接用in或者普通字符串匹配即可。 - 逻辑覆盖不全:仅处理了
1_TYPE列,没有计算2_TYPE、3_TYPE的类型,无法得到你需要的多微生物累加计数结果。
修复实现方案
建议直接用Pandas矢量化操作实现,避免手动写循环容易出现的索引错误,执行效率也更高:
首先导入依赖(如果已经导入可以跳过):
import pandas as pd import matplotlib.pyplot as plt
步骤1:日期格式转换,方便后续按月聚合
# 把DateOnset转为日期格式,注意原始数据是日/月/年格式 ssidf['DateOnset'] = pd.to_datetime(ssidf['DateOnset'], format='%d/%m/%Y', errors='coerce') # 过滤掉没有感染的无DateOnset的记录 infect_df = ssidf[ssidf['DateOnset'].notna()].copy()
步骤2:统计每行各微生物类型的数量
# 初始化四个计数字段为0 infect_df[['gram_pos', 'gram_neg', 'fungi', 'unknown']] = 0 # 遍历三个类型列做累加 type_cols = ['1_TYPE', '2_TYPE', '3_TYPE'] for col in type_cols: # 仅处理当前列非空的行 not_empty = infect_df[col].notna() infect_df.loc[not_empty & infect_df[col].str.contains('Gram Pos'), 'gram_pos'] += 1 infect_df.loc[not_empty & infect_df[col].str.contains('Gram Neg'), 'gram_neg'] += 1 infect_df.loc[not_empty & infect_df[col].str.contains('Fungi'), 'fungi'] += 1 infect_df.loc[not_empty & infect_df[col].str.contains('Unknown'), 'unknown'] += 1
此时你就能得到期望的中间结果,提取对应列即可查看:
mid_result = infect_df[['DateOnset', 'gram_pos', 'gram_neg', 'fungi', 'unknown']]
步骤3:按月聚合统计并绘制堆叠柱状图
# 提取年月维度 infect_df['year_month'] = infect_df['DateOnset'].dt.to_period('M') # 按月求和各类型数量 monthly_count = infect_df.groupby('year_month')[['gram_pos', 'gram_neg', 'fungi', 'unknown']].sum() # 绘制堆叠柱状图 monthly_count.plot(kind='bar', stacked=True, figsize=(15, 7), color=['#1f77b4', '#ff7f0e', '#2ca02c', '#7f7f7f']) plt.xlabel('统计月份') plt.ylabel('微生物出现次数') plt.title('2007年以来各类型微生物月感染次数统计') plt.legend(['革兰氏阳性', '革兰氏阴性', '真菌', '未知']) plt.tight_layout() plt.show()
内容的提问来源于stack exchange,提问作者Anja
相关产品推荐
相关产品推荐

