dataframe for循环_71803倍!超强Pandas循环提速攻略

蓝字,每天一起学 Python,文末领送书福利

5ef804baebc8c9a2c87b0f5383c5dfdf.png

作者:Benedikt Droste

编译:1+1=6@QIML编辑部

推荐 | 编程派公众号(ID:codingpy)

前言

如果你使用Python和Pandas进行数据分析,循环是不可避免要使用的。然而,即使对于较小的DataFrame来说,使用标准循环也是非常耗时的,对于较大的DataFrame来说,你懂的

e05eec838cf570311ee74ea2d6cbc7b9.png

。今天,公众号为大家分享一个关于Pandas提速的小攻略,助你一臂之力!

fd308011f7d12aca942f88f14fc89008.png

相关文章

1、30倍!使用Cython加速Python代码

2、CuPy:将Numpy提速700倍!

3、10个提高工作效率的Pandas小技巧

4、高逼格使用Pandas加速代码,向for循环说拜拜!

标准循环

Dataframe是Pandas对象,具有行和列。如果使用循环,你将遍历整个对象。Python不能利用任何内置函数,而且速度非常慢。 我们创建了一个包含65列和1140行的Dataframe。它包含了2016-2019赛季的足球比赛结果。我们希望创建一个新列,用于标注某个特定球队是否打了平局。

7a281812a154041191af2c9b41ea1726.png 85f30ca025ab8aafece357c4b01f2c22.png

正如你看到的,这个循环非常慢,花了20.7秒。让我们看看如何才能更有效率。

iterrows:快321倍

在第一个例子中,我们循环遍历了整个DataFrame。Iterrows为每一行返回一个 Series,因此它以索引对的形式遍历DataFrame,以Series的形式遍历目标列。这使得它比标准循环更快:

c89810ddd108a788e89e1941acea212d.png b8d1cc5633ec2c451820eb578709f90e.png

该代码运行时间为87毫秒比标准循环快321倍

但是,我们建议不要使用它,因为有更快的选择,而且iterrows不能保留行之间的 dtype。这意味着,如果你在dataframe dtypes上使用iterrows ,它会被更改,这可能会导致很多问题。如果一定要保留dtypes,也可以使用itertuple。这里我们不详细讨论,你可以在这里找到官方文件:

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.itertuples.html?source=post_page-----805030df4f06----------------------

Apply:快811倍

apply本身并不快,但与DataFrame结合使用时,它具有很大的优势。这取决于apply表达式的内容。 如果它可以在Cython中执行,那么apply要快得多。

我们可以在Lambda函数中使用apply。 所要做的就是指定轴,使用axis=1,因为我们希望执行按列操作:

7ad2866b23a57d9940e20e911dc373b6.png

这段代码甚至比以前的方法更快,时间为27毫秒

Pandas Vectorization:快9280倍

我们利用向量化的优势来创建真正高效的代码。关键是要避免案例1中那样的循环代码:

92159750302a80e48156c2a47f2a7eb9.png

我们再次使用了开始时构建的函数。我们所要做的就是改变输入。我们直接将Pandas Series传递给我们的功能,这使我们获得了巨大的速度提升。

Nump Vectorization:快71803倍

在前面的示例中,我们将Pandas Series传递给函数。通过adding.values,我们得到一个Numpy数组:

6259715c860346e5c62b03304340ac19.png

Numpy数组是如此之快,因为我们引用了局部性的好处:

访问局部性(locality of reference)

在计算机科学中,访问局部性,也称为局部性原理,是取决于存储器访问模式频繁访问相同值或相关存储位置的现象的术语。访问局部性有两种基本类型——时间和空间局部性。时间局部性是指在相对较小的持续时间内对特定数据和/或资源的重用。空间局部性是指在相对靠近的存储位置内使用数据元素。当数据元素被线性地排列和访问时,例如遍历一维数组中的元素,发生顺序局部性,即空间局部性的特殊情况。

局部性只是计算机系统中发生的一种可预测的行为。展示强访问局部性的系统是通过使用诸如在处理器核心的流水线级处的高速缓存,用于存储器的预取和高级分支预测器的技术的性能优化的良好候选者。

代码运行了0.305毫秒,比开始时使用的标准循环快了71803倍!

总结

我们比较了五种不同的方法,并根据一些计算将一个新列添加到我们的DataFrame中。我们注意到了速度方面的巨大差异:

59acea6ccc49498a18176b4735742d15.png

请记住:

1、如果确定需要使用循环,则应始终选择apply方法。

2、否则,vectorization总是更好的,因为它更快!

文章参考

[1] https://stackoverflow.com/questions/52673285/performance-of-pandas-apply-vs-np-vectorize-to-create-new-column-from-existing-c

[2 ] https://en.wikipedia.org/wiki/Locality_of_reference

# 文末送书活动 #

活动规则大家请一定要查看,点击这篇推文哦:从今天起,每天至少送大家一本书

这篇推文的福利赠书,改为:《Python 编程快速上手》,送给本篇文章点赞最多、且符合活动要求的精选留言者。

回复下方「关键词」,获取优质资源

回复关键词「 pybook03」,立即获取主页君与小伙伴一起翻译的《Think Python 2e》电子版

回复关键词「书单02」,立即获取主页君整理的 10 本 Python 入门书的电子版

回复关键词「book 数字」,将数字替换成 0 及以上数字,有惊喜好礼哦~

题图:pexels,CC0 授权。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值