如何高效地对Pandas数据框的一行数值求和

3

我有一个包含1.5百万行和8列的 Python 数据帧,我想要合并几列并创建一个新列。我知道如何实现,但想知道哪种方法更快且更有效率。这里是我的代码:

import pandas as pd
import numpy as np
df=pd.Dataframe(columns=['A','B','C'],data=[[1,2,3],[4,5,6],[7,8,9]])

现在我想要实现的是:
df['D']=0.5*df['A']+0.3*df['B']+0.2*df['C']

另一种选择是使用pandas的apply功能
df['D']=df.apply(lambda row: 0.5*row['A']+0.3*row['B']+0.2*row['C'])

当我们有150万行数据和需要合并8个列时,我想知道哪种方法所需时间更短。


所以你基本上是在要求有人为你进行基准测试? - David Arenburg
是的,因为我之前不知道该怎么做。现在我知道了有类似 timeit 的东西存在。 - NG_21
1
好的,你可以直接谷歌一下。虽然有些人会回答任何问题,但SO既不是基准测试服务也不是搜索引擎。 - David Arenburg
@DavidArenburg- 这不仅仅是关于基准测试,如果您看一下答案。有经验的人提供了计算的替代方法,这些方法比我进行基准测试的方法更有效。 - NG_21
2个回答

3

第一种方法更快,因为它是矢量化的:

df=pd.DataFrame(columns=['A','B','C'],data=[[1,2,3],[4,5,6],[7,8,9]])
print (df)

#[30000 rows x 3 columns]
df = pd.concat([df]*10000).reset_index(drop=True)

df['D1']=0.5*df['A']+0.3*df['B']+0.2*df['C']
#similar timings with mul function
#df['D1']=df['A'].mul(0.5)+df['B'].mul(0.3)+df['C'].mul(0.2)

df['D']=df.apply(lambda row: 0.5*row['A']+0.3*row['B']+0.2*row['C'], axis=1)

print (df)

In [54]: %timeit df['D2']=df['A'].mul(0.5)+df['B'].mul(0.3)+df['C'].mul(0.2)
The slowest run took 10.84 times longer than the fastest. This could mean that an intermediate result is being cached.
1000 loops, best of 3: 950 µs per loop

In [55]: %timeit df['D1']=0.5*df['A']+0.3*df['B']+0.2*df['C']
The slowest run took 4.76 times longer than the fastest. This could mean that an intermediate result is being cached.
1000 loops, best of 3: 1.2 ms per loop

In [56]: %timeit df['D']=df.apply(lambda row: 0.5*row['A']+0.3*row['B']+0.2*row['C'], axis=1)
1 loop, best of 3: 928 ms per loop

在另一个大小为1.5MDataFrame测试中,apply方法非常慢:

#[1500000 rows x 6 columns]
df = pd.concat([df]*500000).reset_index(drop=True)

In [62]: %timeit df['D2']=df['A'].mul(0.5)+df['B'].mul(0.3)+df['C'].mul(0.2)
10 loops, best of 3: 34.8 ms per loop

In [63]: %timeit df['D1']=0.5*df['A']+0.3*df['B']+0.2*df['C']
10 loops, best of 3: 31.5 ms per loop

In [64]: %timeit df['D']=df.apply(lambda row: 0.5*row['A']+0.3*row['B']+0.2*row['C'], axis=1)
1 loop, best of 3: 47.3 s per loop

3
使用@jezrael的设置
df=pd.DataFrame(columns=['A','B','C'],data=[[1,2,3],[4,5,6],[7,8,9]])
df = pd.concat([df]*30000).reset_index(drop=True)

使用点积进行计算更加高效。

np.array([[.5, .3, .2]]).dot(df.values.T).T

时间控制

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接