原始文章链接: https://towardsdatascience.com/how-to-make-your-pandas-loop-71-803-times-faster-805030df4f06

一、前言


如果你使用Python和Pandas进行数据分析,循环是不可避免要使用的。然而,即使对于较小的DataFrame来说,使用标准循环也是非常耗时的,对于较大的DataFrame来说,你懂的。今天,公众号为大家分享一个关于Pandas提速的小攻略,助你一臂之力!

二、 标准循环


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

def soc_loop(leaguedf,TEAM,):
    leaguedf['Draws'] = 99999
    for row in range(0, len(leaguedf)):
        if ((leaguedf['HomeTeam'].iloc[row] == TEAM) & (leaguedf['FTR'].iloc[row] == 'D')) | \
            ((leaguedf['AwayTeam'].iloc[row] == TEAM) & (leaguedf['FTR'].iloc[row] == 'D')):
            leaguedf['Draws'].iloc[row] = 'Draw'
        elif ((leaguedf['HomeTeam'].iloc[row] == TEAM) & (leaguedf['FTR'].iloc[row] != 'D')) | \
            ((leaguedf['AwayTeam'].iloc[row] == TEAM) & (leaguedf['FTR'].iloc[row] != 'D')):
            leaguedf['Draws'].iloc[row] = 'No_Draw'
        else:
            leaguedf['Draws'].iloc[row] = 'No_Game'

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

三、 iterrows():快321倍


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

def soc_iter(TEAM,home,away,ftr):
    #team, row['HomeTeam'], row['AwayTeam'], row['FTR']
    if [((home == TEAM) & (ftr == 'D')) | ((away == TEAM) & (ftr == 'D'))]:
        result = 'Draw'
    elif [((home == TEAM) & (ftr != 'D')) | ((away == TEAM) & (ftr != 'D'))]:
        result = 'No_Draw'
    else:
        result = 'No_Game'
    return result

该代码运行时间为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,因为我们希望执行按列操作:

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

五、Pandas Vectorization:快9280倍


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

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

六、Numpy Vectorization:快71803倍


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

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

访问局部性(locality of reference)

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

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

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

七、总结


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

请记住:

  1. 如果确定需要使用循环,则应始终选择apply方法。
  2. 否则,vectorization总是更好的,因为它更快!

文章参考

【转载】pandas中的循环的更多相关文章

  1. Oracle PL/SQL中的循环处理(sql for循环)

    今天来说下Oracle中的循环迭代处理,因为从自己的博客统计中看到,不少网友都搜索了关键字"SQL FOR循环",所以打算在这里说下个人的理解. PL/SQL也和我们常用的编程语言 ...

  2. Wpf中MediaElement循环播放

    原文:Wpf中MediaElement循环播放 前一段时间做了一个项目,里面牵涉到媒体文件的循环播放问题,在网上看了好多例子,都是在xaml中添加为MediaElement添加一个TimeLine,不 ...

  3. Spark与Pandas中DataFrame对比

      Pandas Spark 工作方式 单机single machine tool,没有并行机制parallelism不支持Hadoop,处理大量数据有瓶颈 分布式并行计算框架,内建并行机制paral ...

  4. [转载]java中的标号:outer的作用

    转载自:http://blog.sina.com.cn/s/blog_6f8bd746010136yr.html 标号label 标号提供了一种简单的break语句所不能实现的控制循环的方法,当在循环 ...

  5. Spark与Pandas中DataFrame对比(详细)

      Pandas Spark 工作方式 单机single machine tool,没有并行机制parallelism不支持Hadoop,处理大量数据有瓶颈 分布式并行计算框架,内建并行机制paral ...

  6. pandas中loc-iloc-ix的使用

    转自:https://www.jianshu.com/p/d6a9845a0a34 Pandas中loc,iloc,ix的使用 使用 iloc 从DataFrame中筛选数据 iloc 是基于“位置” ...

  7. Python学习教程:Pandas中第二好用的函数

    从网上看到一篇好的文章是关于如何学习python数据分析的迫不及待想要分享给大家,大家也可以点链接看原博客.希望对大家的学习有帮助. 本次的Python学习教程是关于Python数据分析实战基础相关内 ...

  8. Pandas中DateFrame修改列名

    Pandas中DateFrame修改列名 在做数据挖掘的时候,想改一个DataFrame的column名称,所以就查了一下,总结如下: 数据如下: >>>import pandas ...

  9. SQL中的循环、for循环、游标

    我们使用SQL语句处理数据时,可能会碰到一些需要循环遍历某个表并对其进行相应的操作(添加.修改.删除),这时我们就需要用到咱们在编程中常常用的for或foreach,但是在SQL中写循环往往显得那么吃 ...

随机推荐

  1. 下拉框spinner

    repositories { flatDir { dirs 'libs' //就是你放aar的目录地址 maven { url "https://jitpack.io" } }}d ...

  2. 2.php语言基础

    HP简介 PHP超文本预处理器.是嵌入HTML文件中的服务器端脚本程序.换句话:PHP只能运行在服务器上. 一个HTML文件中,可以包含的代码:HTML代码.CSS代码.JS代码.PHP代码等. PH ...

  3. Yii 三表关联 角色表、角色权限连接表、权限表

    Yii 三表关联 角色表.角色权限连接表.权限表 角色表 role----------------id 唯一序号name 角色名称---------------- 角色权限连接表 lp-------- ...

  4. Redis 5.0.5集群搭建

    Redis 5.0.5集群搭建 一.概述 Redis3.0版本之后支持Cluster. 1.1.redis cluster的现状 目前redis支持的cluster特性: 1):节点自动发现 2):s ...

  5. [WPF自定义控件库] 关于ScrollViewr和滚动轮劫持(scroll-wheel-hijack)

    1. 什么是滚动轮劫持 这篇文章介绍一个很简单的继承自ScrollViewer的控件: public class ExtendedScrollViewer : ScrollViewer { prote ...

  6. python学习——列表生成式,生成器和迭代器

    列表生成式 列表生成式,是python内置的非常简单却强大的可以用来创建list的生成式.它可以极大的简化语句. """列表生成式""" # ...

  7. UGUI的图集处理方式-SpriteAtlas的前世今生

    最糟糕的是人们在生活中经常受到错误志向的阻碍而不自知,真到摆脱了那些阻碍时才能明白过来. —— 歌德 说到UGUI的图集初学者可能觉得没什么难度,包括我刚开始接触的时候也是,甚至你在开发的时候只需要把 ...

  8. Keras(六)Autoencoder 自编码 原理及实例 Save&reload 模型的保存和提取

    Autoencoder 自编码 压缩与解压 原来有时神经网络要接受大量的输入信息, 比如输入信息是高清图片时, 输入信息量可能达到上千万, 让神经网络直接从上千万个信息源中学习是一件很吃力的工作. 所 ...

  9. D-Distance_2019牛客暑期多校训练营(第八场)

    题目链接 Distance 题意 1<=nmh,q<=1e5 q个操作 1 x y z往坐标里加入一个点 2 x y z查询距离该点最近的点的距离(曼哈顿距离) 题解 做法一 将要插入的点 ...

  10. 2018宁夏邀请赛I题 bubble sort(思维题

    https://vjudge.net/problem/Gym-102222I 居然补到个防ak,刚开始不知道啥是循环左移右移(只能移一次),不好想.. 题意:以冒泡排序为背景 给你n,k 问在1~n的 ...