干货!机器学习中,如何优化数据性能

news/2024/7/9 5:50:44

作者 | 中国农业银行研发中心 张梓聪

出品 | AI 科技大本营(ID:rgznai100)

头图 | 下载于视觉中国

得益于覆盖各种需求的第三方库,Python在今天已经成为了研究机器学习的主流工具。不过由于其解释型语言的特性,在运行速度上往往和传统编译型语言有较大差距。特别是当训练数据集非常庞大时,很多时候处理数据本身就会占用大量的时间。

Python中自身提供了非常强大的数据存储结构:numpy库下的ndarry和pandas库下的DataFrame。前者提供了很多list没有实现的便利功能,而后者是最方便的column-row型数据的存储方式,同样提供了大量方便的随机访问函数。

然而不正确的使用很多时候反而会适得其反,给人一种如此高级的三方库性能还不如list手动造轮子的错觉。

本文主要通过优化数据结构以及一些使用中的注意点来提高在大数据量下数据的处理速度。

 

避免使用append来逐行添加结果

很多人在逐行处理数据的时候,喜欢使用append来逐行将结果写入DataFrame或ndarry。类似下面的写法: 

这是非常不好的习惯,numpy或pandas在实现append的时候,实际上对内存块进行了拷贝——当数据块逐渐变大的时候,这一操作的开销会非常大。

下面是官方文档对此的描述:

Numpy: 

Pandas.DataFrame: 

实际上,受list的append操作的影响,开发者会不假思索的认为numpy和pandas中的append也是简单的数组尾部拼接。这实际上是一个很严重的误解,会产生很多不必要的拷贝开销。笔者没有深入研究它们这么设计原因,猜测可能是为了保证拼接后的数组在内存中依然是连续区块——这对于高性能的随机查找和随机访问是很有必要的。

解决办法:

除非必须,在使用DataFrame的部分函数时,考虑将inplace=True。出于保证原始数据的一致性,DataFrame的大部分方法都会返回一个原始数据的拷贝,如果要将返回结果写回,用这种方式效率更高。

除非必须,避免使用逐行处理。Numpy和pandas都提供了很多非常方便的区块选取及区块处理的办法。这些功能非常强大,支持按条件的选取,能满足大部分的需求。同时因为ndarry和DataFrame都具有良好的随机访问的性能,使用条件选取执行的效率往往是高于条件判断再执行的。

特殊情况下,使用预先声明的数据块而避免append。如果在某些特殊需求下(例如当前行的处理逻辑依赖于上一行的处理结果)并且需要构造新的数组,不能直接写入源数据时。这种情况下,建议提前声明一个足够大的数据块,将自增的逐行添加改为逐行赋值。 

这种写法本质上是通过空间换取时间,即便数据量非常巨大,无法一次性写入内存,也可以通过数据块的方式,减少不必要的拼接操作。需要注意的是,数据块的边界处理条件,以避免漏行。

 

避免链式赋值

链式赋值是几乎所有pandas的新人都会在不知不觉中犯的错误,并且产生恼人而又意义不明的SettingWithCopyWarning警告。实际上这个警告是在提醒开发者,你的代码可能没按你的预期运行,需要检查——很多时候可能产生难以调试发现的错误。当使用DataFrame作为输入的第三方库时,非常容易产生这类错误,且难以判断问题到底出现在哪儿。

在继续讲解链式复制前,需要先了解pandas的方法有一部分是返回的是输入数据的视图(view)一部分返回的是输入数据的拷贝(copy),还有少部分是直接修改源数据

上图很好的解释了视图与拷贝的关系。当需要对df2进行修改时,有时候我们希望df1也能被修改,有时候则不希望。而当使用链式赋值时,则有可能产生歧义。这里的歧义指的是面向开发人员的,代码执行是不会有歧义的。 

链式索引,就是对同一个数据连续的使用索引,形如data[1:5][2:3]这样。而链式赋值,就是使用链式索引进行赋值操作。下图是一个链式赋值的例子,解释器给出了SettingWithCopyWarning警告,同时对data的赋值操作也没有成功。 

解决办法:上图中的警告建议,当你想修改原始数据时,使用loc来确保赋值操作被在原始数据上执行,这种写法对开发人员是无歧义的(开发人员往往会误认为链式赋值修改的依然是源数据)。

反过来的情况并不会发生这种歧义。如果开发人员想选取源数据的一部分,修改其中某列的值并赋给新的变量而不修改源数据,那么正常的写法就是无歧义的。 

然而有些隐蔽的链式索引往往并不是简单的像上述情况那样,有可能跨越多行代码,甚至函数。下图的例子中,data_part是对data的选取,而赋值操作又对data_part进行了选取,此时构成了链式索引。 

解决办法:当你确定是要构造拷贝时,明确指明构造拷贝。避免对有可能是视图的中间变量进行修改。 

需要注意的是:DataFrame的索引操作到底是返回视图还是返回拷贝,取决于数据本身。对于单类型数据(全是某一类型的DataFrame)出于效率的考虑,索引操作总是返回视图,而对于多类型数据(列与列的数据类型不一样)则总是返回拷贝。但也请不要依赖这一特性,因为根据内存布局,其行为未必总是一致。最好的方法还是明确指定——如果想要写入副本数据,就在索引时明确拷贝;如果想要修改源数据,就使用loc严格赋值。 

总结

1.可以直接修改源数据就修改源数据,避免不必要的拷贝

2.使用条件索引替代逐行遍历

3.构造数据块替代逐行添加

4.想修改源数据时使用data.loc[row_index, col_index]替代链式赋值

5.想构造副本时严格使用copy消除隐形链式赋值

参考资料:

https://numpy.org/doc/stable/reference/generated/numpy.append.html

https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.append.html

https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#indexing-label

https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#indexing-view-versus-copy

https://zhuanlan.zhihu.com/p/41202576 

扫描下方二维码,添加小助手
即刻加入 AI 科技大本营「读者群」
群内将不定期放送福利
快快加入吧!

http://lihuaxi.xjx100.cn/news/260978.html

相关文章

必看干货:如何在 JavaScript 中实现 8 种基本图形算法

在本文中,我将实现8 种图算法,探索 JavaScript 中图的搜索和组合问题(图遍历、最短路径和匹配)。 这些问题是从《Java编程面试要素》一书中借来的。本书中的解决方案是用 Java、Python 或 C 编写的,具体取决于书的版本…

不说12306你会Die啊?当然不会,但会憋死

别嫌这标题话粗啊,只是突然想起了某小品中的一句台词儿而已。又是一年春运时,几十亿人口开始了兴奋着、痛苦着的大迁徙。12306开通有几年了吧,我今年才第一次用。因为父母要回老家,不想排队那么辛苦,所以才尝试一把网络…

数据结构中几种经典排序简介

参考: https://jingyan.baidu.com/article/fd8044fa79a7265031137aad.html https://www.cnblogs.com/hokky/p/8529042.html 个人比较容易搞混的: 1,简单选择排序:【第一个位置上的数与之后的进行比较!最后结果就是…

深度学习「CV」学习实践指南!

↑↑↑关注后"星标"Datawhale每日干货 & 每月组队学习,不错过Datawhale干货 作者:黄星源、樊亮、陈桦、斯国一深度学习的发展不仅突破了许多视觉难题,也加速了计算机视觉领域相关技术的进步。本文主要从CV数据处理、CV模型&…

windows系统搭建WEB服务器(IIS)

1.WEB服务器也称为网页服务器或HTTP服务器 2.WEB服务器使用的协议是HTTP或HIIPS 3.协议及端口号 HTTP协议端口号:TCP 80HTTPS协议端口号:TCP 443 4.web服务器发布软件 微软:IIS(可以发布web网站和FTP站点)Linux&am…

sqlserver 2014使用时有Cannot find one or more components

好久没用sqlserver,今天打开却出现了一个错误,Cannot find one or more components,令人头疼。在启动Microsoft SQL Server Management Studio时,出现上面的错误提示,程序无法启动.在网搜了一下,发现遇到这样错误的人也不少,但是给出的大部分办法是删除注…

面试官:RabbitMQ本身不支持延迟队列,那你给我实现一个?

以下文章来源方志朋的博客,回复”666“获面试宝典RabbitMQ本身没有延迟队列的支持,但是基于其本身的一些特性,可以做到类似延迟队列的效果:基于死信交换器TTL。以下介绍下相关概念及方法Dead Letter Exchanges消息在队列满足达到一…

在做算法工程师的道路上,你掌握了什么概念或技术使你感觉自我提升突飞猛进?...

点击上方“视学算法”,选择加"星标"或“置顶”重磅干货,第一时间送达作者丨金瀛若愚、桔了个仔、DLing(已授权)来源丨https://www.zhihu.com/question/436874654编辑丨极市平台禁止二次转载,转载须经原作授权…