为什么Pandas的at赋值比列表append后转DataFrame慢近10倍?
性能差异核心原因
- 循环调用
at的开销被多次放大:at确实是Pandas提供的最快的标量存取接口,但单次调用仍然要走索引匹配、类型校验、内存合法性检查等固定逻辑,这些逻辑都存在Python层的调用开销。你测试的样本量接近10万条,等于把这些开销重复执行了近10万次,累积下来耗时自然会很高。 - 列表追加+批量转换的开销极低:Python原生列表的
append是纯C实现的操作,单次调用开销可以忽略不计,所有数据攒完之后仅需要执行一次DataFrame初始化、一次索引设置,这两个操作都是Pandas底层优化过的批量向量化操作,几乎所有逻辑都跑在C层面,Python层的调用次数只有寥寥几次,耗时自然会低一个数量级。
这本质上是Pandas的设计逻辑导致的:Pandas所有的性能优势都建立在批量向量化操作的基础上,逐行循环操作等于完全放弃了它的架构优势,把所有额外开销都放大了几百上千倍。
更优的写法
你这个场景不需要写任何循环,直接用向量化赋值即可,性能比你测试的两种方案都高至少一个数量级:
import pandas as pd import numpy as np import time dt = pd.date_range('2010-01-01','2021-01-01', freq='H') s = pd.Series(data = np.random.randint(0,1000, len(dt)), index = np.random.choice(dt, size=len(dt), replace=False)) d = pd.Series(data = np.nan, index=dt) t = time.time() d.loc[s.index] = np.random.randint(0, 10, size=len(s)) print(time.time()-t)
通常这个写法的耗时会在10毫秒以内,远快于你测试的两种方案。
内容的提问来源于stack exchange,提问作者guyguyguy12345
相关产品推荐
相关产品推荐

