如何加速熊猫字符串函数?

ddx*_*ddx 2 python string split vectorization pandas

我正在使用 Pandas 向量化 str.split() 方法来提取从“~”上的拆分​​返回的第一个元素。我还尝试将 df.apply() 与 lambda 和 str.split() 一起使用来产生等效的结果。使用 %timeit 时,我发现 df.apply() 的执行速度比矢量化版本快。

我读到的关于矢量化的所有内容似乎都表明第一个版本应该有更好的性能。有人可以解释为什么我得到这些结果吗?例子:


     id     facility      
0   3466     abc~24353  
1   4853     facility1~3.4.5.6   
2   4582     53434_Facility~34432~cde   
3   9972     facility2~FACILITY2~343
4   2356     Test~23 ~FAC1  
Run Code Online (Sandbox Code Playgroud)

上面的数据框有大约 500,000 行,我也测试了大约 100 万行,结果相似。以下是一些示例输入和输出:

矢量化


     id     facility      
0   3466     abc~24353  
1   4853     facility1~3.4.5.6   
2   4582     53434_Facility~34432~cde   
3   9972     facility2~FACILITY2~343
4   2356     Test~23 ~FAC1  
Run Code Online (Sandbox Code Playgroud)

Lambda 应用

In [1]: %timeit df['facility'] = df['facility'].str.split('~').str[0]
1.1 s ± 54.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Run Code Online (Sandbox Code Playgroud)

有谁知道我为什么会出现这种行为?
谢谢!

cs9*_*s95 7

Pandas 字符串方法只是“矢量化”,您不必自己编写循环。实际上没有任何并行化正在进行,因为字符串(尤其是正则表达式问题)本质上很难(不可能?)并行化。如果你真的想要速度,你实际上应该在这里使用 python。

%timeit df['facility'].str.split('~', n=1).str[0]
%timeit [x.split('~', 1)[0] for x in df['facility'].tolist()]

411 ms ± 10.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
132 ms ± 302 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
Run Code Online (Sandbox Code Playgroud)

有关何时循环比 Pandas 函数更快的更多信息,请查看带有 Pandas 的 For 循环 - 我什么时候应该关心?.

至于为什么apply更快,我相信apply正在应用的函数(即str.split)比在Series.str.split.