说,我有以下数据框:
df = pd.DataFrame({'a':['a','b','c (not a)', 'this is (random)']*10000})
我想产生以下输出:array(['same as column', 'b', 'c', 'this is']*10000, dtype=object)
为此,我定义了下面的函数并通过 pandas apply 方法传递它。def fn(x):
if ' (' in x:
return x.split(' (')[0]
elif x=='a':
return 'same as column'
else:
return x
df['a'] = df['a'].apply(fn)
然后,其他人建议我使用矢量化,所以我使用下面的代码来生成我想要的输出。df = np.select([df['a'].str.contains(' \('), df['a']=='a'],
[df['a'].str.split(' \(').str[0], 'same as column'],
default=df['a'])
这个矢量化版本的运行速度明显变慢,而不是运行得更快。21.4 ms ± 1.87 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
对于应用方法116 ms ± 21.7 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
用于矢量化这里发生了什么?这正常吗(我认为矢量化是可用的最快选项)?还是我的代码有问题?
最佳答案
您在基准测试中比较不同的实现并得出错误的结论。相关因素是pandas
str
函数不是矢量化的,而是隐式循环。
使用 colab 实例,这些是您的基准测试的结果
%%timeit
df['a'].apply(fn)
100 loops, best of 3: 8.79 ms per loop
%%timeit
np.select([df['a'].str.contains(' \('), df['a']=='a'],
[df['a'].str.split(' \(').str[0], 'same as column'],
default=df['a'])
10 loops, best of 3: 51.3 ms per loop
如果我们想知道时间花在哪里%%timeit
df['a'].str.contains(' \(')
df['a'].str.split(' \(').str[0]
10 loops, best of 3: 48.2 ms per loop
最后比较python的string
split
与 pandas
str.split
%timeit df['a'].str.split(' \(').str[0]
%timeit [x.split(' (')[0] for x in df['a'].to_list()]
10 loops, best of 3: 36.3 ms per loop
100 loops, best of 3: 6.59 ms per loop
关于python - 为什么 numpy select 比通过 apply 方法的自定义函数慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65507935/