如何让Pandas操作加快100倍?

今天我们讨论三种在 Python 数据分析库 Pandas 中加速运算的方法。 Pandas 对于处理存储在电子表格和数据库中的表格数据非常有用。它提供了许多用于操作和转换数据帧或结构数据的功能。

方法 1:使用 itertuples() 迭代数据帧行

解释:有很多地方我们需要迭代数据框的行并进行一些操作。天真地,我们只是检查每一行数据,没有想太多,这里我们用一个简单的求和运算来展示性能变化

generate a dataframe from random numbers


import pandas as pd
import random

df = pd.DataFrame(
{
    "a": [random.randint(0,100) for _ in range(100000)],
    "b": [random.randint(100,200) for _ in range(100000)],
}
)
df
ab
017161
177150
230121
318130
431178
.........
999955183
9999646138
999979133
9999825162
9999998144

100000 rows × 2 columns

situation 1: naive loop

%%timeit

results = []
for i in range(len(df)):
    results.append(df.iloc[i]['a']+df.iloc[i]['b'])
11.9 s ± 297 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

situation 2: using iterrows()

%%timeit
results = []
for index, row in df.iterrows():
    results.append(row['a']+row['b'])

3.61 s ± 156 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

situation 3: using itertuples()

%%timeit
results = []
for row in df.itertuples():
    results.append(row.a+row.b)
69.4 ms ± 3.16 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

结论:使用 itertuples() 比 iterrows() 快 52 倍,比 naive looping 快 171 倍!

方法2:如何高效地创建新的数据框

说明:当我们需要创建一个新的数据框并向其中添加一个新列时,例如,两个现有列的总和

situation 1: get data list, then make a new dataframe from the data

%%timeit

results = []
for row in df.itertuples():
    results.append( (row.a, row.b, row.a+row.b) )
    
new_df = pd.DataFrame(data=results)    
133 ms ± 2.43 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

situation 2: copy the old dataframe to a new one, then make new column using apply() function

%%timeit
new_df = df.copy()

new_df['c'] = new_df.apply(lambda row: row['a']+row['b'],axis=1)
988 ms ± 106 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

situation 3: copy the old dataframe to a new one, then make new column using native dataframe vectorized operation

%%timeit
new_df = df.copy()

new_df['c'] = new_df['a']+new_df['b']
956 µs ± 14 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

结论:如果我们可以在没有 for 循环的情况下利用原生 df 操作,那是最好的,可以快 1000 倍;如果我们有复杂的操作,制作新数据然后从中创建数据框,可能是一个更好的选择

方法3:如何有效地使用apply()函数

在底层,流行的 apply() 函数是一个带有一些开销的 for 循环;在可能的情况下,我们可以利用矢量化操作的好处;我们这里以条件乘法为例

situation 1: use apply() directly

%%timeit
def condition_multi(a):
    if a>30:
        return a*2
    else:
        return a*3
    
    
df['c'] = df['a'].apply(condition_multi)

33.4 ms ± 2.41 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

situation 2: leverage NumPy operations

import numpy as np
%%timeit

df['c'] = np.where(df['a']>30, df['a']*2,df['a']*3)

1.18 ms ± 304 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)

结论:使用 numpy 速度提高了 28 倍!

英文和代码下载(最后一行)

下载地址

全栈程序员的最爱,AI好书必读

在这里插入图片描述
北大出版社,人工智能原理与实践 人工智能和数据科学从入门到精通 详解机器学习深度学习算法原理

人工智能原理与实践 全面涵盖人工智能和数据科学各个重要体系经典

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值