pandas 遍历并修改_Pandas循环提速7万多倍!Python数据分析攻略

乾明 编译整理 
量子位 报道 | 公众号 QbitAI

用Python和Pandas进行数据分析,很快就会用到循环。

但在这其中,就算是较小的DataFrame,使用标准循环也比较耗时。

遇到较大的DataFrame时,需要的时间会更长,会让人更加头疼。

现在,有人忍不了了。他是一位来自德国的数据分析师,名叫Benedikt Droste。

他说,当自己花了大半个小时等待代码执行的时候,决定寻找速度更快的替代方案。

在给出的替代方案中,使用Numpy向量化,与使用标准循环相比,速度提升了71803倍。

50e6bb494c631590ad461e07be1e85af.png

他是怎么实现的?我们一起来看看~

标准循环处理3年足球赛数据:20.7秒

DataFrame是具有行和列的Pandas对象。如果使用循环,需要遍历整个对象。

Python不能利用任何内置函数,而且速度很慢。在Benedikt Droste的提供的示例中,是一个包含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'

a1e2d1046f2dcfabd085703d589b639f.png

在这个案例中是阿森纳,在实现目标之前要确认阿森纳参加了哪些场比赛,是主队还是客队。但使用标准循环非常慢,执行时间为20.7秒。

那么,怎么才能更有效率?

Pandas 内置函数: 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

23cdbfaeed4285abd9698736afa20805.png

代码运行时间为68毫秒,比标准循环快321倍。但是,许多人建议不要使用它,因为仍然有更快的选项,而且iterrows()不能跨行保存dtype。

这意味着,如果你在DataFrame dtypes上使用iterrows(),可以更改它,但这会导致很多问题。

一定要保存dtypes的话,你还可以使用itertuples()。这里我们不详细讨论 ,你可以在这里找到官方文件:

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.itertuples.html

apply ()方法ー快811倍

apply 本身并不快,但与DataFrame结合使用时,它具有优势。这取决于 apply 表达式的内容。如果可以在 Cython 空间中执行,那么apply要快得多,这里的示例就是这种情况。

大家可以在Lambda函数中使用apply。所要做的就是指定这个轴。在本文的示例中,想要执行按列操作,要使用 axis 1:

fcb63f488be7c40298df9ed046488b17.png

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

Pandas向量化—快9280倍

此外,也可以利用向量化的优点来创建非常快的代码。

重点是避免像之前的示例中的Python级循环,并使用优化后的C语言代码,这将更有效地使用内存。只需要稍微修改一下函数:

def soc_iter(TEAM,home,away,ftr):
    df['Draws'] = 'No_Game'
    df.loc[((home == TEAM) & (ftr == 'D')) | ((away == TEAM) & (ftr == 'D')), 'Draws'] = 'Draw'
    df.loc[((home == TEAM) & (ftr != 'D')) | ((away == TEAM) & (ftr != 'D')), 'Draws'] = 'No_Draw'

现在,可以用 Pandas 列作为输入创建新列:

8c71e3dd414dcc330dece90d8957b7e4.png

在这种情况下,甚至不需要循环。所要做的就是调整函数的内容。现可以直接将Pandas 列传递给函数,从而获得巨大的速度增益。

Numpy向量化—快71803倍

在上面的示例中,将将Pandas 列传递给函数。通过添加.values,可以得到一个Numpy数组:

2f1865431f2bae7cb363eacc3473da43.png

因为引用了局部性的好处,Numpy数组的速度非常快,代码运行时间仅为0.305毫秒,比一开始使用的标准循环快71803倍。

谁更强一目了然

最后,Benedikt Droste对上述方案进行了总结。

他说,如果你使用Python、Pandas和Numpy进行数据分析,总会有改进代码的空间。

在对上述五种方法进行比较之后,哪个更快一目了然:

8a3e32ecd9434fd2e4bf193237d348d5.png

从这个图中,可以得出两个结论:

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

  • 2、否则,使用向量化是最好的,因为它更快!

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

直播 | 揭秘最强中文NLP预训练模型

ff9b100ab45b3daeeb1673e09d45ef09.png94904eef11d73c0f4805b49abd47d32d.png

量子位 QbitAI · 头条号签约作者

վ'ᴗ' ի 追踪AI技术和产品新动态

喜欢就点「在看」吧 ! 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/344583.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

教程:用Java创建和验证JWT

“我喜欢编写身份验证和授权代码。” 〜从来没有Java开发人员。 厌倦了一次又一次地建立相同的登录屏幕? 尝试使用Okta API进行托管身份验证,授权和多因素身份验证。 Java对JWT(JSON Web令牌)的支持过去需要进行大量工作&#xf…

AWS re:Invent 2018的5大公告

AWS re:Invent刚刚完成。 这是一个巨大的活动,在拉斯维加斯7家最大的酒店中,有50,000多名与会者,并发布了许多新服务。 无服务器通过新的lambda增强功能和更好的容器支持而继续引起人们的广泛关注。 AWS通过新的“ Outposts”功能…

添加右键菜单_如何在Windows文件夹的右键菜单中添加“打开PowerShell”

原文:https://www.howtogeek.com/165268/how-to-add-open-powershell-here-to-the-context-menu-in-windows/如果您喜欢使用Windows PowerShell而不是命令提示符,那么您可能喜欢从右键单击Windows中的文件夹时得到的上下文菜单中直接访问它。以下是如何做…

多云系统的授权

这是我目前正在致力于消耗SPIFFE( 安全生产身份框架 (Every Production Identity Framework For Everyone )在WSO2的Prabath Siriwardena先生的启发下,在Moratuwa大学的Gihan Dias教授的指导下,通过信任和身份验证在动…

级联选择组件_如何开发一个 Antd 级联多选控件

本文也同步发在掘金上, https:// juejin.cn/post/69149942 41940750343 Intro 这篇文章将从零开始介绍如何开发一个 Antd 的级联多选选择器。先看效果: Github,Sandbox 阅读完这篇文章,不仅可以学会如何实现级联多选的功能,还可以顺便学会: 如何发布一个 Typescript 编写…

node mysql安装目录_nodejs 指定全局安装路径和缓存路径

1、前提:已安装 nodejs(nodejs官网 https://nodejs.org), 并且已将其添加到了环境变量 path 中;2、进入cmd命令行,然后输入 node -v ,测试是否安装成功,出现版本号就表示安装成功3、进入cmd命令行,然后输入…

mysql的sql执行原理图_性能测试MySQL之SQL运行原理

一,MySQL运行原理两个一样的图1,SQL语句执行的过程详细说明如上图所示,当向MySQL发送一个请求的时候,MySQL到底做了什么:a, 客户端发送一条查询给服务器。b, 服务器先检查查询缓存,如果命中了缓存&#xff…

mysql宽字节注入_转宽字节注入详解

在mysql中,用于转义的函数有addslashes,mysql_real_escape_string,mysql_escape_string等,还有一种情况是magic_quote_gpc,不过高版本的PHP将去除这个特性。首先,宽字节注入与HTML页面编码是无关的&#xf…

mysql集群软件有哪些_浅谈数据库集群软件优缺点有哪些

满心狼藉回答时间:2019-12-05向TA提问集群(Cluster)是由两台或多台节点机(服务器)构成的一种松散耦合的计算节点集合,为用户提供网络服务或应用程序(包括数据库、Web服务和文件服务等)的单一客户视图,同时提供接近容错机的故障恢复能力。集群…

错误:在keystone中无法找到默认角色user_第四章 keystone认证组件安装1

1、在控制节点安装rabbitmq、memcached组件apt-get -y install rabbitmq-server memcached python-pymysql # 设置openstack用户 rabbitmqctl add_user openstack password #后一个password是密码,需要特别注意,要与后面组件访问时的密码一致 #设置ope…

ubuntu加了张固态_将ubuntu系统迁移到ssd固态

朋友送了一个固态硬盘给我,因此将原机械硬盘上的系统迁移到固态硬盘上。原机械硬盘(dev/sdb)装有win10和ubuntu双系统。分区情况如下:sda1:ESP分区sda2:资料sda3:资料sda4:swap分区,被我干掉了&…

centos编译mysql5.6_centos7上编译安装mysql5.6

注意,在做实验室统一关闭防火墙做的,在生产环境需要做防火墙规则的,大家要注意,做的时候尽量都是模仿生产环境的,比如服务一般都在/data/soft下面,尽量避免在/usr/local/下面。安装编译mysql所需要的软件[r…

使用ELK堆栈进行日志聚合

1.简介 随着微服务的使用,创建稳定的分布式应用程序和摆脱许多遗留问题变得很容易。 但是微服务的使用也带来了一些挑战, 分布式日志管理就是其中之一。 由于微服务是隔离的,因此它们不共享数据库和日志文件,因此实时搜索&#xf…

mysql主从延时这么长_MySQL主从延迟问题解决

今天我们就来看看为什么会产生主从延迟以及主从延迟如何处理等相关问题。坐好了,准备发车!主从常见架构随着日益增长的访问量,单台数据库的应接能力已经捉襟见肘。因此采用主库写数据,从库读数据这种将读写分离开的主从架构便随之…

生成器作为(快速失败)状态机

这个想法是几周前在设计“ Generator”类时想到的,该类必须将输入发送给封装的Writer 。 实际上,它是Builder模式。 但是,规则有些复杂,用户必须以某种方式调用add...()方法,才能正确生成输出。 不用说,我…

源码包编译安装python_Python3.7源码包编译安装-Go语言中文社区

环境:[rootlocalhost python3]# cat /etc/redhat-releaseCentOS Linux release 7.5.1804 (Core)[rootlocalhost python3]#1、下载Python方式一:方式二:进入https://www.python.org/ftp/python/ 这里存放着所有版本的Python源码。往下拉看到最…

java criteria and_criteria用法

Criteria Query通过面向对象化的设计,将数据查询条件封装为一个对象。简单来讲,Criteria Query可以看作是传统SQL的对象化表示,如:Java代码Criteria criteria session.createCriteria(User.class);criteria.add(Expression.eq(&q…

java jdt_在JDT中使用Java 8 Lambda

java jdt旧 Curmudgeon 认识Smalltalk的Dude 在修改Eclipse Java开发工具 (JDT)项目正在开发的Java 8支持时,我一直在使用这种语言。 我承认我对Java 8中的lambda有点不满意。 当然,这来自于知道Smalltalk (和LISP…

java 1.8签名apk_给Android的APK程序签名和重新签名的方法

签名工具的使用Android源码编译出来的signapk.jar既可给apk签名,也可给rom签名的。使用格式:java –jar signapk.jar [-w] publickey.x509[.pem] privatekey.pk8 input.jar output.jar-w 是指对ROM签名时需使用的参数publickey.x509[.pem] 是公钥文件pri…

使用Oracle验证外部数据

我经常在Corda Slack频道中闲逛,并尽可能回答问题。 我尝试回答的合理数量的问题与Oracle有关。 更具体地说,何时使用一个。 我觉得我可以回答,“当您需要验证可能经常更改的外部数据时使用Oracle”。 我可能在某个时候写了一个类似的答案。 …