如何加快pandas字符串的功能?

时间:2018-06-07 14:55:38

标签: python string pandas split vectorization

我使用pandas vectorized str.split()方法从“〜”中提取从拆分返回的第一个元素。我也尝试使用带有lambda和str.split()的df.apply()来产生等效的结果。当使用%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  

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

矢量

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)

Lambda Apply

In [2]: %timeit df['facility'] = df['facility'].astype(str).apply(lambda facility: facility.split('~')[0])
650 ms ± 52.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

有谁知道我为什么会这样做? 谢谢!

1 个答案:

答案 0 :(得分:2)

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)

有关何时循环比pandas函数更快的更多信息,请查看For loops with pandas - When should I care?

至于为什么apply更快,我认为函数apply正在应用(即str.split)比字符串拆分轻得多发生在Series.str.split的内容中。