python - 为什么 Pandas apply 比矢量化内置函数更快

标签 python pandas numpy vectorization

<分区>

我在练习vectorization with Pandas ,并且我发现了一个违反直觉的情况,当使用一系列内置向量化方法比应用一个朴素的 Python 函数(提取系列中所有数字的第一个数字)慢时:

import sys
import numpy as np
import pandas as pd

s = pd.Series(np.arange(100_000))

def first_digit(x):
    return int(str(x)[0])

s.astype(np.str).str[0].astype(np.int) # 218ms "built-in"
s.apply(first_digit)                   # 104ms "apply"
s.map(first_digit)                     # 104ms "map"
np.vectorize(first_digit)(s)           #  78ms "vectorized"

所有 4 个实现都产生相同的 Pandas 系列,我完全理解 vectorized 函数调用可能比每个元素 apply/map.

但是,我很困惑为什么使用 buil-in 方法速度较慢...虽然我也对实际答案感兴趣,但我更感兴趣的是什么是最小的我必须学习的一组工具才能评估我对性能的假设

我的假设是方法调用链正在创建 2 个额外的中间 Pandas 系列,并且贪婪地评估这些系列的值,导致 CPU 缓存未命中(必须从 RAM 加载中间系列)。

按照该假设的步骤,我不知道如何确认或证伪:

  1. 中间系列/numpy 数组是贪婪还是惰性评估?
  2. 会不会导致 CPU 缓存未命中?
  3. 我还需要考虑哪些其他解释?

我的测量截图:

jupyter screenshot

最佳答案

简而言之,你的问题是

s.astype(np.str).str[0].astype(np.int)

将您的操作融合在一起,然后迭代系列,或为每个操作创建一个临时系列,以及如何验证这一点?

我的假设(我猜你也是)是后者。你有正确的解释,但如何测试?

我的建议是:

s1=s.astype(np.str)
s2=s1.str[0]
s3=s2.astype(np.int)

查看每个操作需要多长时间以及 3 个操作总共需要多长时间。很可能每个操作将花费大约相同的时间(每个操作的复杂性大致相同)这将强烈表明我们的假设是正确的。如果前两个操作不花时间,但最后,几乎所有时间,我们的假设可能是错误的。

关于python - 为什么 Pandas apply 比矢量化内置函数更快,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63604469/

相关文章:

Python TypeError 与逻辑迭代数据值

python - 使用多个数据集创建 seaborn 散点图矩阵(PairGrid)

python - 带有空字符的 numpy.genfromtxt csv 文件

python - Windows 7 python 32 上 python.exe 的内存 - Numpy 仅使用一半的可用内存?

python - 将 Numpy 导入函数

python - python 在脚本中哪里查找文件?

python - 我的 for 循环内部函数有什么错误。错误 : "string indices must be integers". 在空闲状态下运行它,但它不会给我错误

python - 从一个 Pandas 系列中减去另一个 Pandas 系列而不为缺失数据创建 NaN 值

python - Groupby()和 Pandas 中的聚合

python - 在Python中如何在二维列表中找到内部列表的最大长度?