为什么在DataFrame上应用功能要比在Series上快得多?
import time
import pandas as pd
import numpy as np
my_range = np.arange(0, 1_000_000, 1)
df = pd.DataFrame(my_range, columns=["a"])
my_time = time.time()
df["b"] = df.a.apply(lambda x: x ** 2)
print(time.time() - my_time)
# 7.199899435043335
my_range = np.arange(0, 1_000_000, 1)
df = pd.DataFrame(my_range, columns=["a"])
my_time = time.time()
df["b"] = df.apply(lambda x: x ** 2)
print(time.time() - my_time)
# 0.09276103973388672
答案 0 :(得分:2)
时间差的原因是apply
上的Series
会调用Series
中每个值的函数。但是对于DataFrame
,它仅对每一列调用一次函数。
>>> my_range = np.arange(0, 10, 1, )
>>> df = pd.DataFrame(my_range, columns=["a"])
>>> _ = df.a.apply(lambda x: print(x, type(x)) or x ** 2)
0 <class 'int'>
1 <class 'int'>
2 <class 'int'>
3 <class 'int'>
4 <class 'int'>
5 <class 'int'>
6 <class 'int'>
7 <class 'int'>
8 <class 'int'>
9 <class 'int'>
>>> _ = df.apply(lambda x: print(x, type(x)) or x ** 2)
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
Name: a, dtype: int32 <class 'pandas.core.series.Series'>
[... repeated one more time ...]
在这里,我将不理会第二次讨论(根据DYZ,这是检查是否可以采用快速路径的熊猫方式)。
因此,在您的情况下,您有2个调用(DataFrame)与1_000_000个调用(系列)。这已经解释了大多数时间差异。
鉴于它们的工作方式有多不同,这根本不是可比的。如果将功能应用于整个系列,则完全不同(更快):
import pandas as pd
import numpy as np
my_range = np.arange(0, 1_000_000, 1, )
df = pd.DataFrame(my_range, columns=["a"])
%timeit df.a.apply(lambda x: x ** 2)
# 765 ms ± 4.28 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit df.apply(lambda x: x ** 2)
# 63.2 ms ± 1.48 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit df.a ** 2 # apply function on the whole series directly
# 10.9 ms ± 481 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)