Python “这是一种方法吗?”;矢量化用于中等数据集,速度相对较慢
我有这个数据框:Python “这是一种方法吗?”;矢量化用于中等数据集,速度相对较慢,python,pandas,dataframe,Python,Pandas,Dataframe,我有这个数据框: df = pd.DataFrame({'a' : np.random.randn(9), 'b' : ['foo', 'bar', 'blah'] * 3, 'c' : np.random.randn(9)}) 此功能: def my_test2(row, x): if x == 'foo': blah = 10 if x == 'bar': blah = 20 if
df = pd.DataFrame({'a' : np.random.randn(9),
'b' : ['foo', 'bar', 'blah'] * 3,
'c' : np.random.randn(9)})
此功能:
def my_test2(row, x):
if x == 'foo':
blah = 10
if x == 'bar':
blah = 20
if x == 'blah':
blah = 30
return (row['a'] % row['c']) + blah
然后,我将创建3个新列,如下所示:
df['Value_foo'] = df.apply(my_test2, axis=1, x='foo')
df['Value_bar'] = df.apply(my_test2, axis=1, x='bar')
df['Value_blah'] = df.apply(my_test2, axis=1, x='blah')
它运行正常,但当我将我的_test2变得更复杂,并将df扩展到数千行时,它的运行速度很慢——我听到的上述描述是“矢量化”的吗?我可以轻松地加快速度吗?正如Andrew、Ami Tavory和Sohier Dane在评论中提到的,您的解决方案中有两个“缓慢”的方面:
.apply()
通常速度较慢,因为它在发动机罩下循环.apply(…,axis=1)
速度非常慢(即使与.apply(…,axis=0)
相比也是如此)In [74]: d = {
....: 'foo': 10,
....: 'bar': 20,
....: 'blah': 30
....: }
In [75]: d
Out[75]: {'bar': 20, 'blah': 30, 'foo': 10}
In [76]: for k,v in d.items():
....: df['Value_{}'.format(k)] = df.a % df.c + v
....:
In [77]: df
Out[77]:
a b c Value_bar Value_blah Value_foo
0 -0.747164 foo 0.438713 20.130262 30.130262 10.130262
1 -0.185182 bar 0.047253 20.003828 30.003828 10.003828
2 1.622818 blah -0.730215 19.432174 29.432174 9.432174
3 0.117658 foo 1.530249 20.117658 30.117658 10.117658
4 2.536363 bar -0.100726 19.917499 29.917499 9.917499
5 1.128002 blah 0.350663 20.076014 30.076014 10.076014
6 0.059516 foo 0.638910 20.059516 30.059516 10.059516
7 -1.184688 bar 0.073781 20.069590 30.069590 10.069590
8 1.440576 blah -2.231575 19.209001 29.209001 9.209001
针对90K行DF的计时:
In [80]: big = pd.concat([df] * 10**4, ignore_index=True)
In [81]: big.shape
Out[81]: (90000, 3)
In [82]: %%timeit
....: big['Value_foo'] = big.apply(my_test2, axis=1, x='foo')
....: big['Value_bar'] = big.apply(my_test2, axis=1, x='bar')
....: big['Value_blah'] = big.apply(my_test2, axis=1, x='blah')
....:
1 loop, best of 3: 10.5 s per loop
In [83]: big = pd.concat([df] * 10**4, ignore_index=True)
In [84]: big.shape
Out[84]: (90000, 3)
In [85]: %%timeit
....: for k,v in d.items():
....: big['Value_{}'.format(k)] = big.a % big.c + v
....:
100 loops, best of 3: 7.24 ms per loop
结论:矢量化方法的速度快1450倍…我认为
df.apply
只是迭代地应用函数。最好根据if
语句对数据帧进行3次过滤,然后编写函数,使其能够接受df
作为参数,并以非迭代方式更改该参数。要添加到Andrew的注释中,第一行相当于df.a%df.c+10
,但它的运行时间为1.6秒,而不是2.31毫秒。任何时候使用axis=1时,它都不是完全矢量化的。Axis=1将函数应用于单个行,并且几乎总是比一次应用于整个列的完全矢量化操作慢得多。非常好-感谢您花时间-我将在代码中使用时间,在与完整函数一起使用时也将使用时间