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

Pandas 1.3.5与1.4.2版本loc方法性能提升原因咨询

Pandas 1.4版本loc逐行赋值性能提升来源

你观测到的1.3.5到1.4.2的loc性能差距,来自两个没有放在版本说明主条目的底层实现优化,针对的正好是测试用例覆盖的「逐行遍历+单单元格loc赋值」场景。

测试场景的核心开销来源

测试代码通过iterrows()逐行遍历,每次循环调用loc给单个单元格赋值,这类操作的开销在旧版本主要来自两部分:

  • 每次loc调用都会走完整的通用索引对齐、全DataFrame Block类型校验流程,和批量切片/赋值走完全相同的重逻辑
  • 每次写操作都会重复解析列位置、获取底层数组内存指针,没有针对同列连续写入做缓存

1.4版本的具体优化点

  • 单标量赋值快速路径
    1.3及更早版本中,不管是批量赋值还是单个单元格赋值,loc都会执行完整的多Block兼容检查、轴索引对齐逻辑,哪怕操作只涉及单个行列对,也会遍历所有列存储块做类型校验,10万次循环就会重复触发10万次冗余检查。
    1.4版本新增了单标量赋值的快速分支:当检测到传入的行、列参数都是单个标签,且赋值标量和目标列dtype兼容时,会直接跳过通用流程,定位到目标列的底层数组直接写入值,单步操作开销直接降到旧版本的1/3左右。
  • 列位置缓存复用
    1.3版本每次loc写操作都要重新对列名做哈希查找,确认目标列在BlockManager中的偏移位置。1.4版本新增了连续访问的列位置缓存,当连续对同一个列执行写入操作时,不需要重复做哈希查找,进一步压缩了逐行操作的固定开销。

补充说明:哪怕1.4版本对这个场景做了优化,逐行iterrows()+loc赋值依然是性能极差的写法,测试用例的需求直接用矢量化写法data_frame["value"] = 1可以在毫秒级完成,性能比逐行循环高两个数量级以上。

测试复现代码

import timeit
import pandas as pd

data = {"id": [str(i) for i in range(100_000)]}
data_frame = pd.DataFrame(data=data)

def test_loc_read():
    print(pd.__version__)

    data_frame["value"] = 0
    for label, _ in data_frame.iterrows():
        data_frame.loc[label, "value"] = 1

if __name__ == "__main__":
    print(timeit.timeit(test_loc_read, number=3))

同硬件环境实测结果:Pandas 1.3.5执行3次循环总耗时约50秒,Pandas 1.4.2执行3次循环总耗时约14秒,与测试数据一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 01:51:24