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

Python含if条件的逐行循环提速方法咨询(600万行数据集)

如何加速百万级数据集的NaN填充操作

嗨,这个问题我太有发言权了!处理600万行的数据集时,Python的普通逐行循环完全是性能灾难,更别说你代码里还加了print(i)——这个IO操作会把速度拖得更慢,先赶紧把它删掉!

先说说原代码的核心问题

  1. Pandas逐行操作天生低效:Pandas是基于向量化设计的,底层用C实现了批量操作优化,而你用for循环逐行调用iloc,相当于绕过了所有优化,每一行都要做Python层面的逻辑判断和数据定位,600万行的话耗时会非常夸张。
  2. 重复索引定位开销:每次iloc[i-1,3]都要重新定位行和列,这是额外的性能浪费。
  3. 不必要的IO拖慢:循环里的print(i)会频繁输出到控制台,IO操作的速度比内存计算慢几个数量级,直接拖慢整个流程。

最优解决方案:用Pandas内置向量化函数(秒级处理)

你的需求是:当open price为NaN时,用上一行的close price填充。这个逻辑完全可以用Pandas的shift()和fillna()组合实现,全程向量化操作,底层C执行,600万行基本几秒就能搞定:

import pandas as pd

# 1. 生成上一行的close price序列(向下偏移1行)
prev_close = price3['close price'].shift(1)

# 2. 用prev_close填充open price中的NaN值
price3['open price'] = price3['open price'].fillna(prev_close)

如果你的数据是按symbol分组的(不同股票/标的的价格不能互相填充),一定要加上分组操作,避免逻辑错误:

# 按symbol分组后,用组内上一行的close price填充当前行的open price NaN
price3['open price'] = price3.groupby('symbol').apply(
    lambda group: group['open price'].fillna(group['close price'].shift(1))
).reset_index(level=0, drop=True)

关于你问的apply()如何加条件(不推荐大数据量)

虽然apply()也能实现,但它本质还是逐行遍历,速度远不如向量化操作,600万行的话依然会很慢。不过满足你的疑问,这里给出实现方式:

# 先新增一列存储上一行的close price
price3['prev_close'] = price3['close price'].shift(1)

# 用apply逐行判断,填充NaN
price3['open price'] = price3.apply(
    lambda row: row['prev_close'] if pd.isna(row['open price']) else row['open price'],
    axis=1  # axis=1表示逐行处理
)

# 用完可以删掉临时列
price3.drop('prev_close', axis=1, inplace=True)

同样,如果需要分组,也要在groupby后使用apply。


额外小贴士

  • 永远优先选择Pandas的内置向量化函数(比如fillna、shift、replace等),避免手动写循环。
  • 如果一定要用循环(比如逻辑极其复杂),可以试试用numba库给循环加速,或者转换成NumPy数组后再循环,速度会比直接操作DataFrame快很多。
  • 调试时不要逐行打印,改用print(f"Processed {i/1000000:.2f}M rows")每隔100万行打印一次,减少IO开销。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:32:33