【问题标题】:How to speed up pandas apply lambda function for numba engine如何加速 pandas 为 numba 引擎应用 lambda 函数
【发布时间】:2021-10-17 09:46:06
【问题描述】:

对于加速 pandas 的案例,我了解了 numba 引擎,可以显着加速。

在最近的情况下,我喜欢使用带有 lambda 的 argsort 来获取任意索引,但它似乎很慢。为什么 lambda 会减慢代码速度?如何编写适当的应用函数以不进一步损害速度??我什至将 lambda 函数包装在 nb.njit 中,但仍然看不到更多的加速。

从逻辑上讲 np.argmax 和 np.argsort [-1] 是相同的,但是例如可以使用 np.argsort 来获取中位数。所以我想确认是否有更好的方法来写lambda x: np.argsort(x)[5],例如

import pandas as pd
import numpy as np
import numba as nb
import timeit
import sys


def f1():
    a = pd.DataFrame(range(10000000))
    return a.rolling(10).apply(np.argmax, engine='numba', raw=True)

nb.njit((nb.int64)(nb.float64[:]))
def f(x):
    return np.argsort(x)[5]

def f2():
    a = pd.DataFrame(range(10000000))
    return a.rolling(10).apply(f, engine='numba', raw=True)
if __name__ == '__main__':
    print(timeit.timeit(lambda: f2(), number=10) / 10)
(base) xxx:~$ python test.py f1
1.4400632409029641
(base) xxx:~$ python test.py f2
5.061740894208197

【问题讨论】:

  • 我只见过 numba 与装饰器一起使用,但我记得因为它是 JIT 编译的,所以第一次执行很慢,后续执行很快。你试过timeit吗?
  • 字面上没有变化,在 apply 函数必须再次应用 10000000 - 1 次,所以 timeit 不应该做任何重要的事情

标签: python pandas performance numpy numba


【解决方案1】:

这些是我使用timeit得到的结果

In [1]: %timeit a.rolling(10).apply(np.argmax, engine='numba', raw=True)
16.9 ms ± 477 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [2]: %timeit a.rolling(10).apply(np.argmax, raw=True)
176 ms ± 3.07 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [3]: %timeit a.rolling(10).apply(l1, engine='numba', raw=True)
79.8 ms ± 1.93 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [4]: %timeit a.rolling(10).apply(l1, raw=True)
116 ms ± 1.65 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

请注意,我使用 a = pd.DataFrame(range(100_000)) 进行了此操作。

【讨论】:

  • 它没有改变任何东西,我用 timeit 更新了。对于 10000000 函数将在编译后应用 10000000 - 1 倍
  • 我的结果显示将引擎设置为 numba 更快。
  • 是的。但问题是 np.argmaxlambda x: np.argsort(x)[-1] 在逻辑上是等价的,但为什么使用 numba enigine lambda x: np.argsort(x)[-1] 需要 79.8 毫秒和 np.argmax 16.9 毫秒。为什么这样??我需要以几乎相似的方式编写 lambda
  • 我想确认我所写的内容是否最好??
  • 希望我没有误会,但即使np.argsort(x)[-1]np.argmax 的结果相同,但语义不同:argsort 需要排序并且是O(nlogn),即使你只想要可以在 O(n) 中访问的信息,这就是 np.argmax 正在做的事情。
猜你喜欢
  • 1970-01-01
  • 2018-07-28
  • 1970-01-01
  • 2022-09-23
  • 1970-01-01
  • 1970-01-01
  • 2019-05-22
  • 2018-12-23
  • 1970-01-01
相关资源
最近更新 更多