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

Pandas填充NaN性能低下:如何避免逐行迭代?

优化Expedia数据集缺失值填充性能:告别几小时等待

嘿,太懂这种痛苦了——我之前处理类似规模的数据集时,也踩过逐行迭代的坑,几小时跑不完真的让人崩溃!核心问题在于Python级别的逐行循环完全没利用到pandas的矢量化优势,咱们直接用矢量化操作把速度提上去,500万行数据几秒就能搞定。

问题根源:为什么逐行迭代这么慢?

pandas的iterrows()或者手动循环每一行,本质是在Python层面逐行处理,每次循环都要做类型检查、索引定位等额外开销,500万次累加起来就是天文数字。而pandas的矢量化操作是底层用C实现的,批量处理数据,效率差好几个数量级。

最优解决方案:两种矢量化填充方法

方法1:用字典映射(最快最简洁)

把你的lookup表转换成字典,然后用map()匹配srch_destination_id对应的填充值,再结合fillna()完成填充:

# 先把lookup表转成字典:key是srch_destination_id,value是对应的填充值
# 假设你的lookup表是lookup_df,包含列'srch_destination_id'和'fill_value'(你用来填充的列)
lookup_dict = lookup_df.set_index('srch_destination_id')['fill_value'].to_dict()

# 一步完成填充:只对NaN的位置用映射值替换
df['prop_location_score2'] = df['prop_location_score2'].fillna(df['srch_destination_id'].map(lookup_dict))

如果lookup表中存在某些srch_destination_id没有对应值的情况,可以给map()加个默认值:

from collections import defaultdict
# 用默认值(比如0或者均值)处理不存在的id
lookup_default = defaultdict(lambda: 0, lookup_dict)
df['prop_location_score2'] = df['prop_location_score2'].fillna(df['srch_destination_id'].map(lookup_default))

方法2:用merge合并填充(适合复杂lookup场景)

如果你的lookup表有多个维度的填充规则,或者需要更直观的关联操作,可以用merge()把原数据和lookup表合并,再用合并后的列填充:

# 按srch_destination_id左合并原数据和lookup表
merged_df = df.merge(lookup_df, on='srch_destination_id', how='left', suffixes=('', '_fill'))

# 用合并后的填充列替换原列的NaN
df['prop_location_score2'] = df['prop_location_score2'].fillna(merged_df['fill_value_fill'])

额外性能优化小技巧

  • 优化数据类型:把srch_destination_id转换成整数类型(比如df['srch_destination_id'] = df['srch_destination_id'].astype(int)),减少内存占用同时加快匹配速度;
  • 提前去重lookup表:确保lookup表中每个srch_destination_id只有一条记录,避免合并时产生重复行;
  • 避免链式操作:尽量一次性完成赋值,减少中间临时DataFrame的创建。

这些方法都是矢量化操作,500万行数据的填充操作绝对能在几十秒内完成,完全不用再等几小时!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:59:28