用Python数据分析时,他将Pandas循环提速7万多倍

干编整理

量子比特报告|微信官方账号QbitAI

Python和Pandas用于数据分析,loops很快也会用到。

但其中,即使是很小的数据帧,使用标准循环也是需要时间的。

当遇到更大的数据帧时,所需的时间会更长,会更让人头疼。

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

他说,当他花了半个小时等待代码执行时,他决定寻找一个更快的替代方案。

在给定的替代方案中,Numpy向量化的速度比标准循环高71,803倍。

他是怎么做到的?一起看看吧~

3年足球比赛数据的标准周期处理:20.7秒

DataFrame是一个包含行和列的Pandas对象。如果使用循环,就需要遍历整个对象。

Python不能利用任何内置函数,而且很慢。在Benedikt Droste提供的示例中,它是一个65列1140行的Dataframe,包含2023-2023赛季的足球比赛结果。

要解决的问题是:创建一个新的列来表示某个特定的团队是否抽到了。你可以这样开始:

def soc_loop(leaguedf,TEAM,):league df[' Draws ']=99999 for row in range(0,len(league df)):if((league df[' home TEAM '])。iloc[row]==TEAM)(league df[' FTR ']。iloc[row]==' D ')| \((league df[' away team ']。iloc[row]==TEAM)(league df[' FTR ']。iloc[row]==' D '):league df[' Draws ']。iloc[row]=' Draw ' elif((league df[' home team '])。iloc[row]==TEAM)(league df[' FTR ']。iloc[row]!=' D ')| \((league df[' away team ']。iloc[row]==TEAM)(league df[' FTR ']。iloc[row]!=' D '):league df[' Draws ']。iloc[row]=' No _ Draw ' else:league df[' Draws ']。iloc[row]='No_Game '

在这种情况下,它是阿森纳。在达成目标之前,需要确认阿森纳参加了哪些比赛,是主队还是客队。但是标准周期很慢,从010到31019执行时间是20.7秒。

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

熊猫内置函数:iteraws () 快321倍。

在第一个示例中,整个数据帧在一个循环中被遍历。Iterrows()为每一行返回一个序列,它以索引对的形式遍历数据帧,以序列的形式遍历感兴趣的列。这使得它比标准循环更快:

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 '返回结果

代码时间是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结合使用有优势。这取决于应用表达式的内容。如果可以在Cython空间执行,那么apply要快得多,这里的例子就是这种情况。

你可以在Lambda函数中使用apply。你要做的就是指定这个轴。在本文的示例中,如果您想要执行逐列操作,您需要使用axis 1:

这段代码甚至比前面的方法还要快,完成时间用时27毫秒。

熊猫矢量化—速度提高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列作为输入:

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

Numpy矢量化—速度提高71803倍

在上面的例子中,熊猫列将被传递给函数。通过添加。值,可以得到一个Numpy数组:

由于局部性的优势,Numpy数组非常快。运行的代码时间只有0.305毫秒,比一开始使用的标准循环快了71803倍。

谁更强一目了然。

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

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

对比以上五种方法,哪种更快一目了然:

从该图可以得出两个结论:

1.如果要使用循环,应该始终选择apply方法。2.否则最好用矢量化,因为速度更快!原始链接:

https://towards data science . com/how-to-make-your-pandas-loop-71-803-times-fast-805030 df4f 06

—结束—

真诚招聘

量子正在招聘编辑/记者,工作地点在北京中关村。期待有才华有热情的同学加入我们!详情请在QbitAI对话界面回复“招聘”二字。

量子qbitai头条签约作者

追踪AI技术和产品的新趋势。

其他教程

偷拍直播违法吗(偷拍直播是否违法)

2023-1-6 12:24:21

其他教程

全世界飞翔的鸟歌词(贝子鸟全口叫声)

2023-1-6 12:26:24

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索