当前位置: 首页 > 图灵资讯 > 行业资讯> 如何在Python中使用Pandas高效填充千万级数据集中的缺失值?

如何在Python中使用Pandas高效填充千万级数据集中的缺失值?

来源:图灵python
时间: 2026-08-12 21:59:11
fillna() 卡死的主要原因是默认情况下按列填充时的索引对齐和混合类型反复推断,导致内存和CPU双爆;首先检查dtype、强转数值列,按列处理,禁用自动类型升级。

为什么 fillna() 直接用在千万行会卡死吗?

因为默认的 fillna()axis=0(按列)时,内部会尝试做完整的索引对齐和类型推断,特别是当列出混合类型(如 object 列里混着 None、空字符串、数字字符串),Pandas 会逐元素调用 isna() 并反复 infer 类型,内存和 CPU 双爆。看到过程不动,很有可能卡在类型推断或链式拷贝上。

实操建议:

立即学习“Python免费学习笔记(深入);

  • 先用 df.dtypes 检查每列的真实性 dtype,显然,应该是值,但被识别为值 object 的列用 pd.to_numeric(..., errors='coerce') 强转
  • 避免调用整个表 df.fillna(value) —— 改为按列处理,只处理需要填充的列
  • 禁用自动类型改进:输入自动类型改进:输入自动类型改进: downcast=False(默认是 'infer'),防止 Pandas 尝试压缩 int64 → int32
数值列用 fillna(method='ffill') 为什么结果不对?

因为 method='ffill' 默认按 axis=0(即垂直填充),但如果您的数据按时间分块读取和拼接,索引不连续或重复,ffill 会跨块“泄露”前一块末尾值到后一块开头,造成逻辑错误。这不是真的。 bug,是设计如此 —— 无论商业语义如何,它只识别索引顺序。

实操建议:

立即学习“Python免费学习笔记(深入);

  • 确认是否真的需要前进填充:大部分千万场景(如传感器日志、订单流量)都要按业务分组填充,比如 df.groupby('device_id')['temp'].ffill()
  • 若必须全局 ffill,首先重置索引:df = df.reset_index(drop=True),否则,稀疏索引会使填充物跳过大量行驶
  • limit 谨慎使用参数:设置 limit=1 看似安全,但并行 chunk 相邻性在处理过程中可能会被允许 chunk 边界处漏填
如何用 chunksize + dtype 预设规避 OOM?

读 CSV 时不用 pandas.read_csv() 一次性加载,但使用 chunksize 但是,如果不提前指定流动处理; dtype,每个 chunk 类型仍将独立推断,导致后续 concat 时列类型不一致(例如一个 chunk 的 price 是 另一个是float64, object),导致隐式转换和内存翻倍。

Python 3.14.2

Python 3.14.2是Python编程语言于2025年12月5日发布的稳定版本,属于3.14系列的第二次维护更新。该版本包含18个修复项目,重点解决多过程、数据和正则表达模块的回归问题,修复CVE-2025-12084等安全漏洞。这个版本标志着Python发展的一个重要里程碑,即自由线程模式(删除GIL)正式得到官方支持。

下载

实操建议:

立即学习“Python免费学习笔记(深入);

  • 先用小样本跑一次 pd.read_csv('sample.csv', nrows=10000).dtypes,保存为字典 dtypes_dict
  • 读取时显式传入:pd.read_csv(path, chunksize=50000, dtype=dtypes_dict, low_memory=False)
  • 每个 chunk 填充后立即写入磁盘(如 parquet):chunk_filled.to_parquet(f'filled_{i}.parq', index=False),不要把它堆在内存里 concat
scikit-learnSimpleImputer 真比 Pandas 快吗?

只有数值列多,缺乏模式规则(如固定列需要平均填充) —— 因为 SimpleImputer 底层用 NumPy 向量化计算,不要去 Pandas 的 object 循环路径。但它强制输入是二维的 array,列名和索引会丢失,无法处理 object 列字符串填充(如用众数填充分类变量)。

实操建议:

立即学习“Python免费学习笔记(深入);

  • 统一处理数值列:提取 df.select_dtypes(include='number').values,用 SimpleImputer(strategy='mean').fit_transform(),再塞回原 DataFrame 对应位置
  • 单独处理分类列:使用 df['category'].mode()[0] 获取众数,重复使用 fillna(),别强塞进 SimpleImputer
  • 注意 SimpleImputermissing_values 默认是 np.nan,假如存储在数据中 'N/A'-999,手动更换或更改参数

数千万数据的填充瓶颈往往不是算法本身,而是类型混乱、索引冗余、内存碎片 —— 先 fix dtype 和索引,比换库更立竿见影。