
本文介绍如何使用pandas的`fillna(0)`方法批量将dataframe中的nan值替换为0,并结合向量化操作替代低效的`iterrows()`循环,显著提升数据处理性能与代码可维护性。
在数据分析实践中,频繁遇到含缺失值(NaN)的CSV表格需进行数值计算——例如按行加权求和、条件赋值等。原始代码中采用iterrows()逐行遍历并手动float()转换,不仅性能低下(尤其对万行以上数据),还易因NaN引发ValueError或TypeError,且嵌套的try-except掩盖了真正的数据质量问题。
最优解:向量化预处理 + 向量化计算
首先,用df.fillna(0)一次性将所有NaN替换为0(若仅需特定列,可传入字典:df.fillna({'first column': 0, 'second column': 0}))。随后,直接通过列名索引获取数值列,利用Pandas内置的向量化运算完成计算,彻底避免Python循环:
import pandas as pd
import numpy as np
# 读取数据(推荐添加dtype参数避免类型推断错误)
df = pd.read_csv('documents/doc.csv',
error_bad_lines=False, # 已弃用,建议改用on_bad_lines='skip'
on_bad_lines='skip')
# 步骤1:统一填充NaN为0(安全且高效)
df = df.fillna(0)
# 步骤2:提取目标列并转为数值类型(自动处理空字符串等异常)
cols = ["first column", "second column", "third column", "fourth column", "fifth column"]
df[cols] = df[cols].apply(pd.to_numeric, errors='coerce').fillna(0)
# 步骤3:向量化计算(无需循环)
var1, var2, var3 = df["first column"], df["second column"], df["third column"]
var4, var5 = df["fourth column"], df["fifth column"]
# 构建布尔掩码:var4为0或原为NaN(现已被fill为0)
mask_var4_zero = (var4 == 0)
# 分别计算两种逻辑下的结果
final_grade = np.where(
mask_var4_zero,
np.round(0.25 * (var1 + var2 + var3) / 3 + 0.75 * var5, 1),
np.round(0.166 * (var1 + var2 + var3) / 3 + 0.33 * var4 + 0.5 * var5, 1)
)
# 将结果写入新列
df['final_grade'] = final_grade关键优势与注意事项:
- ✅ 性能提升:向量化操作比iterrows()快10–100倍,且内存友好;
- ✅ 健壮性增强:pd.to_numeric(..., errors='coerce')将非法字符串转为NaN,再经fillna(0)统一处理,避免float()抛异常;
- ⚠️ 避免隐式类型转换:勿依赖row["col"]自动转float,原始CSV中数字可能被读为字符串;
- ⚠️ 跳过首行? 若首行为标题,read_csv默认已处理,无需i==0: continue;若确需跳过首数据行,用skiprows=1参数更清晰;
- ? 调试建议:用df.isna().sum()检查各列缺失值分布,用df.dtypes确认列数据类型,再决定是否需要astype(float)。
最终,该方案将冗长易错的循环逻辑压缩为几行声明式代码,兼具可读性、可维护性与生产级鲁棒性。










