为什么应用熊猫可以比矢量内置插件更快

问题描述

我正在练习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加载中间系列)。 / p>

遵循该假设的步骤,我不知道如何确认或伪造:

  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)

查看每个操作花费的时间以及这三个操作花费的时间。每个操作最有可能花费大约相同的时间(每个操作的复杂度大约相同),这很可能表明我们的假设是正确的。如果前两个操作不花时间,而几乎所有时间都花在最后,那么我们的假设可能是错误的。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...