dataframe for循环_Python Pandas 遍历DataFrame的正确姿势 速度提升一万倍

f79d156562cff121554962833ac1c4b7.png

最近做科研时经常需要遍历整个DataFrame,进行各种列操作,例如把某列的值全部转成pd.Timestamp格式或者将某两列的值进行element-wise运算之类的。大数据的数据量随便都是百万条起跳,如果只用for循环慢慢撸,不仅浪费时间也没效率。在一番Google和摸索后我找到了遍历DataFrame的至少8种方式,其中最快的和最慢的可以相差12000倍

本文以相加和相乘两种操作为例,测试8种方法的运行速度,并附上示范代码。

测试环境

Macbook Pro Retina with TouchBar (13inch, 2018) i5 8GB 512GB
OS: macOS Catalina 10.5.2
Python 3.7.5 (default, Nov  1 2019, 02:16:23)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin

示范用数据

本来想造100万笔的,但是100万笔跑%timeit要跑很久,最后造了3000笔,己经足以体现运行速度差异。为了避免快取影响,每个子实验进行前都会用这个代码重造数据。

import 

20e75cddccd65ff8c0cfa2370fa4f894.png
aaa、bbb是本文要操作的对象;ccc、ddd不会被操作到,只是要增大数据框的大小,模拟读入整个数据框和只读取aaa、bbb两列的速度差别;eee用来存放结果

实验1 - 两列元素相加

# aaa + bbb

实验1 结果

df 

实验2 - 两列元素相乘

# aaa * bbb

实验2 结果

df 

速度比较

我把结果可视化,方便比较运行速度。(顺便练习画图)

d0e2fe4dabd0a80d9753213c2b830c38.png

可以看到最快的数组操作和最慢的for+iloc相比差了将近万倍,是秒级和微秒级的差别。所有方法运行速度大小关系如下(由慢至快):for循环+iloc < pd.iterrows < for循环+at < pd.apply pd列表构造 = np列表构造 < pd数组操作 < np数组操作。pd和np列表构造的速度几乎一样,np列表构造略快一些(1.15毫秒和1.09毫秒的差别),所以实验只做pd列表构造。

把两个秒级操作去掉,详细地比较一下

42df59912b9efd3d10e64424b3856bb8.png

列表构造把除了数组操作以外的其他方法按在地上磨擦,数组操作把列表构造按在地上磨擦。值得注意的是,for循环+iat的组合比pandas提供的最快遍历方法apply快40%左右,也就是说就算不懂apply的用法,只要把loc/iloc改成at/iat,依然可以有明显的提速。另外,DataFrame的栏位很多的时候,apply_limit方法其实会比对对整个数据框apply快很多(因为不用每次读取整个数据框),只是示范数据的栏位不多所以在这里显现不出差异。

pandas的数组操作和numpy的数组操作单独对比:

48b5a77703479aa59117b6c4f4d401cf.png

列表构造的运行速度是毫秒级的,数组操作是微秒级,np数组操作是pd数组操作的两倍。

作图代码

x 

结论

优先使用numpy数组操作!不能数组操作的时候用列表构造!

能用at/iat就不用loc/iloc,能用apply就不用迭代,能用数组操作就不用其他方法。

运行速度:np数组操作 > pd数组操作 >>> np列表构造 = pd列表构造 >>> for循环+at > pd(分片).apply > pd.apply >>> pd.iterrows > for循环+iloc

关于at/iat和loc/iloc的速度比较,请见参考资料[4]。

参考资料

  1. How To Make Your Pandas Loop 71803 Times Faster
  2. rain润:10分钟python图表绘制 | seaborn入门(二):barplot与countplot
  3. seaborn.barplot
  4. 老狼:简单两步,大幅提高python数据处理速度
  5. seaborn.plotting_context
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值