我很好奇为什么 pandas.Series.div() 在应用于 pandas 数字系列时比/= 慢。例如:
python3 -m timeit -s 'import pandas as pd; ser = pd.Series(list(range(99999)))' 'ser /= 7'
1000 loops, best of 3: 584 usec per loop
python3 -m timeit -s 'import pandas as pd; ser = pd.Series(list(range(99999)))' 'ser.div(7)'
1000 loops, best of 3: 746 usec per loop
我认为这是因为前者改变了系列,而后者返回了一个新系列。但如果是这样的话,既然 div() 和 mul() 不如/= 和 */那么快,那为什么还要费心实现它们呢? 即使您不想就地更改系列,ser/7 仍然比 .div() 更快:
python3 -m timeit -s 'import pandas as pd; ser = pd.Series(list(range(99999)))' 'ser / 7'
1000 loops, best of 3: 656 usec per loop
那么 pd.Series.div() 有什么用以及它使它变慢的原因是什么?
最佳答案
Pandas .div
显然实现了类似于 /
和 /=
的除法。
拥有单独的.div
的主要原因是Pandas采用了一种语法模型,其中数据帧上的操作由连续过滤器的应用程序来描述,例如.div
、.str
等允许简单的串联:
ser.div(7).apply(lambda x: 'text: ' + str(x)).str.upper()
以及对多个参数的更简单支持(参见.func(a, b, c)
不可能用二元运算符编写)。
相比之下,如果没有 div
,同样的内容可以写成:
(ser / 7).apply(lambda x: 'text: ' + str(x)).str.upper()
/
操作可能会更快,因为与 .div()
相比,与 /
运算符相关的 Python 开销更少。
相比之下,x/= y
运算符替换了构造x = x/y
。
对于基于 NumPy 的矢量化容器(如 Pandas),它的作用稍稍超出了这一点:它使用 就地 操作,而不是创建 的(可能耗时和内存)副本x
。这就是为什么 /=
比 /
和 .div()
更快的原因。
请注意,虽然在大多数情况下这是等效的,但有时(如本例)它可能仍然需要转换为不同的数据类型,这在 Pandas 中自动完成(但在 NumPy 中则不然)。
关于python - pandas.Series.div() vs/=,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57060488/