Dai*_*ang 2 python numpy dataframe pandas
numpy/pandas 因其底层加速(即矢量化)而闻名。
条件评估是代码中随处可见的常见表达式。
然而,apply直观地使用 pandas dataframe 函数时,条件评估似乎非常慢。
我的代码示例apply如下:
def condition_eval(df):
x=df['x']
a=df['a']
b=df['b']
if x <= a:
d = round((x-a)/0.01)-1
if d <- 10:
d = -10
elif x >= b:
d = round((x-b)/0.01)+1
if d > 10:
d = 10
else:
d = 0
return d
df['eval_result'] = df.apply(condition_eval, axis=1)
Run Code Online (Sandbox Code Playgroud)
此类问题的特征可能是:
numpy/pandas 解决此类问题的最佳实践是什么?
还有一些想法。
在我看来,矢量化加速之所以有效的原因之一是因为底层CPU有某种矢量指令(例如SIMD,intel avx),它依赖于一个事实,即计算指令具有确定性行为,即无论如何输入数据是,经过固定数量的CPU周期后可以获得结果。因此,并行化此类操作很容易。
然而,cpu中的分支执行要复杂得多。首先,相同条件评估的不同分支具有不同的执行路径,因此它们可能会导致不同的CPU周期。现代 CPU 甚至利用了许多技巧,例如分支预测,这会产生更多的不确定性。
所以我想知道 pandas 是否以及如何尝试加速此类矢量条件评估操作,以及它们是否是处理此类计算工作负载的更好实践。
这应该是等价的:
import pandas as pd
import numpy as np
def get_eval_result(df):
conditions = (
df.x.le(df.a),
df.x.gt(df.b),
)
choices = (
np.where((d := df.x.sub(df.a).div(0.01).round().sub(1)).lt(-10), -10, d),
np.where((d := df.x.sub(df.b).div(0.01).round().add(1)).gt(10), 10, d),
)
return np.select(conditions, choices, 0)
df = df.assign(eval_result=get_eval_result)
Run Code Online (Sandbox Code Playgroud)
我的答案基本上计算每个分支的结果,然后使用 numpy 语法来指定应使用哪些结果。这可以稍微优化,但由于它使用纯矢量化函数,它应该比使用.apply.
| 归档时间: |
|
| 查看次数: |
132 次 |
| 最近记录: |