干货!机器学习中,如何优化数据性能
作者 | 中国农业银行研发中心 张梓聪
出品 | 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 科技大本营「读者群」
群内将不定期放送福利
快快加入吧!
相关文章:

JavaScript深入理解对象方法——Object.entries()
Object.entries() Object.entries()方法返回一个给定对象自身可枚举属性的键值对数组,其排列与使用 for...in 循环遍历该对象时返回的顺序一致(区别在于 for-in 循环也枚举原型链中的属性)。 语法 Object.entries(obj) 参数 obj可以返回其可枚…

C#非对称加密程序
using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; using System.IO; using System.Text; using System.Security.Cryptography; namespace 非对称加密 { /// <summa…

Exchange Server2013 系列十:证书的配置
Exchange Server2013 系列十:证书的配置杜飞经过前面的配置,基本上可以进行简单的邮件通讯了,但是当用户通过OWA连接邮箱时会报下面的提示:其他一些服务,如 Outlook Anywhere 和 Exchange ActiveSync,也要求…

高级程序员到底高级在哪里?
身为一名技术人,你是否遇到过这些情况?工作效率低:别人1小时就能修复的bug,你需要3小时没有存在感:技术趋势看不透,和同事聊天完全插不上话技术提升慢:苦熬996,但升职加薪仍然遥遥无…

AlexNet 网络详解及Tensorflow实现源码
版权声明:本文为博主原创文章,未经博主允许不得转载。 1. 图片数据处理2. 卷积神经网络 2.1. 卷积层2.2. 池化层2.3. 全链层3. AlexNet4. 用Tensorflow搭建完整的AlexNet5. 用AlexNet识别猫狗图片 5.1. 定义分类5.2. 训练网络5.3. 验证1. 图片数据处理 一…

.net反射详解(转)
摘自:http://www.cnblogs.com/knowledgesea/archive/2013/03/02/2935920.html 概述反射 通过反射可以提供类型信息,从而使得我们开发人员在运行时能够利用这些信息构造和使用对象。 反射机制允许程序在执行过程中动态地添加各种功能。 运行时类型标识 …

C# 多网卡 Server Listen
VC和BCB中做一个Server的监听程序,只需要指定端口,然后监听(Listen)就行了.在C#找不到这个函数了,慢慢看MSDN,怎么需要指定IP和Port才能监听,那么多网卡的机器应该怎么写程序呢?下面的程序可以解释怎么去做. TcpListener 类别会提供简易的方法,用以在封锁的同步模式…

赠书 | 一文了解预训练语言模型
来源 | 博文视点头图 | 下载于视觉中国近年来,在深度学习和大数据的支撑下,自然语言处理技术迅猛发展。而预训练语言模型把自然语言处理带入了一个新的阶段,也得到了工业界的广泛关注。通过大数据预训练加小数据微调,自然语言处理…
写了六个相同功能的函数之后,我学到了什么
本文讲的是写了六个相同功能的函数之后,我学到了什么,几周之前,一个社区在 Free Code Camp’s Forum 上发起了非官方的算法大赛。 这个题目看似很简单:返回小于数字 N 的所有 3 或者 5 的倍数的和,N 是函数的参数。 但…

libevent介绍
libevent是一款事件驱动的网络开发包 由于采用 c 语言开发 体积小巧,跨平台,速度极快。 通常我们在建立服务器的处理模型的时候,主要是下面集中模型;(1) a new Connection 进来,用 fork() 产生一个 Process 处理。 (2) a new Connecti…

蓝色起源载人火箭7月首飞,贝索斯即将实现儿时愿望
整理 | 寇雪芹出品 | AI 科技大本营(ID:rgznai100)头图 | 下载于ICphoto美国当地时间6月7日早,亚马逊创始人、世界首富贝索斯(Jeff Bezos)在社交媒体上发帖表示,自己将在7月20日乘坐蓝色起源(Bl…

使用jquery.more.js来实现点击底部更多后, 底部加载出新的数据
<div class"bus-nav-bar ft12"><div class"navt bor-r-c pos-rel {if $int 0}fwbold{/if}"><a href"portal.php?modmerchant&actionvoucherlist&int0">全部订单</a><em class"pos-abs"></…

ios开发学习-手势交互(Gesture)效果源码分享
qianqianlianmengios开发学习-手势交互(Gesture)效果源码分享 All Around Pull View 介绍:实现视图四个方向(上下左右)都能够拖动更新(pull to refresh)。 编译测试,测试环境…

通过C#实现集合类纵览.NET Collections及相关技术
概述:在真正的对象化开发项目中,我们通常会将常用的业务实体抽象为特定的类,如Employee、Customer、Contact等,而多数的类之间会存在着相应的关联或依存关系,如Employee和Customer通过Contact而产生关联、Contact是依赖…

TIOBE 6 月榜单: Python 有望超越 C 语言成为第一名
整理 | 苏宓出品 | CSDN(ID:CSDNnews)头图 | 下载于ICphotoTIOBE 官方最新发布了 6 月的编程语言榜单,这个月榜单中又有怎样的发展趋势?Python 有望成为第一名在本月榜单中,位居第二名的 Python 与第一名 C…

使用dom4j解析XML例子
包括三个文件:studentInfo.xml(待解析的xml文件), Dom4jReadExmple.java(解析的主要类), TestDom4jReadExmple.java(测试解析的结果) 代码运行前需先导入dom4j架包。 studentInfo.xml文件(该文件放在本项目目录下)内容如下: <?…

mkdir、rmdir命令、head、tail命令
mkdir-p 递归创建目录11里面都是空目录rmdir删除空目录 -p 当子目录被删除后使它也成为空目录的话,则一并删除步骤:先删除11/22/33 发现22目录空了,因为33删了,于是再删22,空了再删11head默认是前10行 –n指定几行tai…

Linux Find 命令精通指南
作者:Sheryl Calish Linux find 命令是所有 Linux 命令中最有用的一个,同时也是最混乱的一个。它很难,因为它的语法与其他 Linux 命令的标准语法不同。但是,它很强大,因为它允许您按文件名、文件类型、用户甚至是时间戳…

【安全运维】 linux 系统账户,网络,简易安全加固方案(第一部分),经测试可行...
前言讲到linux系统账户的管理以及安全,就必须涉及 /etc/passwd /etc/shadow 这2个文件这里以截图中文字说明的方式,来分析这2个文件的内容,并且给出一些实用的安全加固方案注意,本文会持续更新,后续加入的内容都以直…

不用深度学习,怎么提取图像特征?
来源 | 小白学视觉头图 | 下载于ICphoto图像分类是数据科学中最热门的领域之一,在本文中,我们将分享一些将图像转换为特征向量的技术,可以在每个分类模型中使用。VATboxVATbox,作为n一个我们所暗示的,涉及增值税问题&a…

课程第五天内容《基础交换 五》
2019独角兽企业重金招聘Python工程师标准>>> 以太网/LAN(local area network )的相关概念: 问题: 信号传输距离有限; 解决方案: 中继器 - 放大电信号,延长信息的传输距离࿱…

C#综合揭秘——Entity Framework 并发处理详解
引言 在软件开发过程中,并发控制是确保及时纠正由并发操作导致的错误的一种机制。从 ADO.NET 到 LINQ to SQL 再到如今的 ADO.NET Entity Framework,.NET 都为并发控制提供好良好的支持方案。 并发处理方式一般分为乐观必并发与悲观必并发两种࿰…

@2021高考生,用 Python 分析专业“钱景”
来源 | 关于数据分析于可视化头图 | 下载于ICphoto2021年的高考在昨日拉开帷幕,十年的寒窗苦读,终于到了最后见分晓的时候了。在这么一场关键的考试当中,除了考试前努力奋斗,考场上认真答题,考后的志愿填报也是极其的重…

Linux下C语言的fgets与fputs
使用的是 CentOS gcc编译下面程序 显示warning: the gets function is dangerous and should not be used.问题出在程序中使用了 gets Linux 下gcc编译器不支持这个函数,解决办法是使用 fgets fgets()函数的基本用法为: fgets(char * s,int size,FILE * …

linux发行版的用户交互
1 cli,即command line interface 纯命令行的交互方式,该命令行界面是由shell提供的。 linux内核本身也自带了一个console,即linux console,它是基于frame buffer的。 cli的界面都是基于ncurses库开发的。 2 GUI,graphi…

C#中在应用程序和DLL使用消息
在C#中采用的是事件驱动方式,但在我们使用的过程中,有时候通过调用系统原有的消息,处理起来会比较简单一些,特别是在处理与DLL文件的交互时,的确是非常的方便。 在C#中使用自定义消息 在C#中使用自定义消息非常简单&…

倪光南院士:openEuler与全球开发者共同推动计算产业发展
今日,以“创造最好的OS,成就更好的我们”为主题的 openEuler Developer Day 2021在北京成功举行。本次大会由openEuler社区发起,产业组织专家、学者、企业领袖和开发者们围绕多样性计算、云原生全栈、全场景协同等技术方向共同探讨和创新。大…

jhello框架-ajax
2019独角兽企业重金招聘Python工程师标准>>> 现在的web开发没有ajax都没法活,所以在jhello中实现了一个简单的ajax交互,使用json作为载体。 在上篇《交互》中讲到一种交互的方式是把数据放入Model中,通过ModelAndView类返回到视图…

发微信模版消息换行用\n
发微信模版消息换行用\n发微信模版消息换行用\n发微信模版消息换行用\n发微信模版消息换行用\n发微信模版消息换行用\n转载于:https://blog.51cto.com/xuqin/1974131

二次元会让人脸识别失效吗?
来源 | PyTorch 开发者社区责编 | 寇雪芹头图 | 下载于ICphoto人脸识别也遇到坑了,识别得了三次元,却对二次元无效。迪士尼的技术团队,正在开发这一算法,以帮助动画制作者进行后期搜索。团队利用 PyTorch,效率得到很大…