Pandas大数据量内存优化
头条创作挑战赛一、背景介绍
Pandas在处理大数据(尤其是列比较多的场景)时,如果不做优化,内存占用还是很大的,下面通过一个实例来说明可以怎样优化
首先,生成一批18万的数据,每条数据151列importpandasaspdimportnumpyasnpdefgenbigdata(csvfile:str,bigdatacount90000):charsabcdefghijklmnopqrstuvwxyzdatespd。daterange(start20200101,periodsbigdatacount,freq30s)bigdatacols〔Name〕forgroupinrange(1,31):bigdatacols。extend(〔fdatestr{group},fbool{group},fint{group},ffloat{group},fstr{group}〕)bigdata〔〕foriinrange(0,bigdatacount):row〔fNameItem{(i1)}〕forinrange(0,30):row。extend(〔str(dates〔i〕),i20,np。random。randint(10000,100000),10000np。random。random(),chars〔np。random。randint(0,26)〕15〕)bigdata。append(row)dfpd。DataFrame(databigdata,columnsbigdatacols)df。tocsv(csvfile,indexNone)ifnamemain:修改存放路径以及模拟数据量(默认9万)genbigdata(。filescustombigdata。csv,180000)复制代码
查看生成的数据格式,可以看到每一行有151列
保存数据后,先查看一下内存占用情况importpandasaspddefinfomemory(csvfile:str):dfpd。readcsv(csvfile)print(df。info(memoryusagedeep))ifnamemain:infomemory(。filescustombigdata。csv)复制代码
打印结果如下,可以看到当前内存占用为862。1MBclasspandas。core。frame。DataFrameRangeIndex:180000entries,0to179999Columns:151entries,Nametostr30dtypes:bool(30),float64(30),int64(30),object(61)memoryusage:862。1MB复制代码
查看不同类型的内存占用情况definfomemorybydtype(csvfile:str):dfpd。readcsv(csvfile)fordtypein〔bool,float64,int64,object〕:dtypeselecteddf。selectdtypes(include〔dtype〕)memmeanbitdtypeselected。memoryusage(deepTrue)。mean()memmeanmbmemmeanbit10242print(fmeanmemoryusage:{dtype:7}{memmeanmb:。3f}M)复制代码
输出结果如下,其中object类型占用内存最多meanmemoryusage:bool0。166Mmeanmemoryusage:float641。329Mmeanmemoryusage:int641。329Mmeanmemoryusage:object12。494M复制代码二、优化方案
查看某个类型的内存占用量definfomemusagemb(pdobj):ifisinstance(pdobj,pd。DataFrame):memusagepdobj。memoryusage(deepTrue)。sum()else:memusagepdobj。memoryusage(deepTrue)转换为MB返回returnf{memusage10242:02。3f}MB复制代码
int和float类型
对于int和float类型的数据,Pandas加载到内存中的数据,默认是int64和float64。一般场景下的数据,用int32和float32就足够了,用numpy。iinfo和numpy。finfo可以打印对应类型的取值范围Machineparametersforint32min2147483648max2147483647Machineparametersforint64min9223372036854775808max9223372036854775807复制代码Machineparametersforfloat32。。。maxexp128max3。4028235e38nexp8minmaxMachineparametersforfloat64。。。maxexp1024max1。7976931348623157e308nexp11minmax复制代码
分别优化int和float的类型defoptimizeintandfloat():dfintdf。selectdtypes(include〔int64〕)dfintconverteddfint。apply(pd。tonumeric,downcastunsigned)dffloatdf。selectdtypes(include〔float64〕)dffloatconverteddffloat。apply(pd。tonumeric,downcastfloat)print(intbefore,infomemusagemb(dfint))print(intconverted,infomemusagemb(dfintconverted))print(floatbefore,infomemusagemb(dffloat))print(floatconverted,infomemusagemb(dffloatconverted))复制代码
优化后的结果如下,内存减少50左右intbefore41。199MBintconverted20。599MBfloatbefore41。199MBfloatconverted20。599MB复制代码
object类型中的普通str数据
获取object类型数据,并调用describe()展示统计信息
对于区分度较低的str1到str30,一共只有26个可能的值,可以考虑转换为Pandas中的categroy类型,这里将区分度小于40的列转换为category类型defoptimizeobj():dfobjdf。selectdtypes(include〔object〕)dfobjconvertedpd。DataFrame()forcolindfobj。columns:uniquecountlen(dfobj〔col〕。unique())totalcountlen(dfobj〔col〕)将区分度小于40的列转换为category类型ifuniquecounttotalcount0。4:dfobjconverted。loc〔:,col〕dfobj〔col〕。astype(category)else:dfobjconverted。loc〔:,col〕dfobj〔col〕print(objectbefore,infomemusagemb(dfobj))print(objectconverted,infomemusagemb(self。dfobjconverted))复制代码
执行结果如下,降低了300M的内存objectbefore774。602MBobjectconverted409。047MB复制代码
object类型中的date数据defoptimizedatestr():dfdatepd。DataFrame()dfdateconvertedpd。DataFrame()forcolnameindf。columns:ifcolname。startswith(datestr):dfdate。loc〔:,colname〕df〔colname〕dfdateconverted。loc〔:,colname〕pd。todatetime(df〔colname〕)print(datebefore,infomemusagemb(dfdate))print(dateconverted,infomemusagemb(dfdateconverted))复制代码
执行结果如下,也降低了300M的内存datebefore391。388MBdateconverted41。199MB复制代码三、总体优化
综合以上的优化方法,并封装为类PandasMemoryOptimizeDemoimportpandasaspdimportnumpyasnpclassPandasMemoryOptimizeDemo:df:pd。DataFramedfintconverted:pd。DataFramedffloatconverted:pd。DataFramedfobjconverted:pd。DataFramedfdateconverted:pd。DataFramedefinit(self,csvfile:str):self。csvfilecsvfileself。dfpd。readcsv(self。csvfile)staticmethoddefinfomemusagemb(pdobj):ifisinstance(pdobj,pd。DataFrame):memusagepdobj。memoryusage(deepTrue)。sum()else:memusagepdobj。memoryusage(deepTrue)转换为MB返回returnf{memusage10242:02。3f}MBdefoptimizeintandfloat(self):dfintself。df。selectdtypes(include〔int64〕)self。dfintconverteddfint。apply(pd。tonumeric,downcastunsigned)dffloatself。df。selectdtypes(include〔float64〕)self。dffloatconverteddffloat。apply(pd。tonumeric,downcastfloat)print(intbefore,self。infomemusagemb(dfint))print(intconverted,self。infomemusagemb(self。dfintconverted))print(floatbefore,self。infomemusagemb(dffloat))print(floatconverted,self。infomemusagemb(self。dffloatconverted))defoptimizeobj(self):dfobjself。df。selectdtypes(include〔object〕)self。dfobjconvertedpd。DataFrame()forcolindfobj。columns:uniquecountlen(dfobj〔col〕。unique())totalcountlen(dfobj〔col〕)将区分度小于40的列转换为category类型ifuniquecounttotalcount0。4:self。dfobjconverted。loc〔:,col〕dfobj〔col〕。astype(category)else:self。dfobjconverted。loc〔:,col〕dfobj〔col〕print(objectbefore,self。infomemusagemb(dfobj))print(objectconverted,self。infomemusagemb(self。dfobjconverted))defoptimizedatestr(self):dfdatepd。DataFrame()self。dfdateconvertedpd。DataFrame()forcolnameinself。df。columns:ifcolname。startswith(datestr):dfdate。loc〔:,colname〕self。df〔colname〕self。dfdateconverted。loc〔:,colname〕pd。todatetime(self。df〔colname〕)print(datebefore,self。infomemusagemb(dfdate))print(dateconverted,self。infomemusagemb(self。dfdateconverted))defoptimizeall(self):self。optimizeintandfloat()self。optimizeobj()self。optimizedatestr()dfconvertedself。df。copy()dfconverted〔self。dfintconverted。columns〕self。dfintconverteddfconverted〔self。dffloatconverted。columns〕self。dffloatconverteddfconverted〔self。dfobjconverted。columns〕self。dfobjconverteddfconverted〔self。dfdateconverted。columns〕self。dfdateconvertedprint(before,self。infomemusagemb(self。df))print(converted,self。infomemusagemb(dfconverted))ifnamemain:optimizedemoPandasMemoryOptimizeDemo(。filescustombigdata。csv)optimizedemo。optimizeall()复制代码
执行结果如下,优化效果还是很明显的before862。149MBconverted105。207MB复制代码四、直接优化readcsv方法
写代码的过程中,如果每次都按照这样的步骤,其实还是很繁琐,那能不能在调用readcsv方法时就进行优化呢?
接下来就一起来探索一下
在PyCharm中,点击readcsv进入源码,发现该方法提供了非常丰富的参数(50),这里只列举需要的参数defreadcsv(filepathorbuffer:FilePathReadCsvBuffer〔bytes〕ReadCsvBuffer〔str〕,GeneralParsingConfigurationdtype:DtypeArgNoneNone,convertersNone,DatetimeHandlingparsedatesNone,inferdatetimeformatFalse,keepdatecolFalse,dateparserNone,lowmemorycparserdefaults〔lowmemory〕,memorymapFalse,storageoptions:StorageOptionsNone,):locals()shouldneverbemodifiedkwdslocals()。copy()复制代码
可以直接指定dtype和parsedates,最终代码如下defbigdataoptimizedreadcsv(self):dtypedict{}dateindexes〔〕foriinrange(1,31):dtypedict〔fint{i}〕int32dtypedict〔ffloat{i}〕float32dtypedict〔fstr{i}〕categorydateindexes。append(5(i1)1)self。dfpd。readcsv(self。csvfile,dtypedtypedict,parsedatesdateindexes)print(optimizedreadcsv:,self。infomemusagemb(self。df))复制代码
执行结果如下,内存占用也大大降低了optimizedreadcsv:105。207MB
电脑一直嗡嗡的响是什么原因?电脑主机响声大怎么解决?电脑可以说是我们经常会接触到的一种电器,比如玩大型网游办公等等,都需要电脑来实现。我们在开机使用电脑的时候,电脑里的各种零件运行时是不会发出声响的,如果发出异常声响或者响声比较大的
旧电视别换不锈钢脸盆啦!来乐视换新机至高可抵1500CNMO新闻近日,乐视官宣将开展乐视电视以旧换新活动。据CNMO了解,该活动将分两个时间段举行,分别为9月6日10日和9月17日19日。此次消费者可更换的有超5X55超4X75F6
科学家已经评估了将飞往火星的宇航员的辐射危险在最近发表在空间物理学上的一项研究中,一个国际科学家小组讨论了太阳辐射对宇航员的影响。这个问题与将要前往火星的任务尤其相关。暴露于电离辐射是宇航员在飞往火星飞行期间的主要健康风险之
如果小行星撞向地球,核弹能起作用吗?相信大家在电影屏幕上看过很多次这种场景科学家发现一颗巨大的小行星冲向地球,人类唯一的希望就是派出一个团队在星球体内植入核弹。尽管经历了几次挫折,勇敢的团队最终还是成功了,小行星爆炸
什么是iPhone扩容机?用起来体验如何?现在iPhone的扩容机在各大平台随处可见,如果你不注意,一般都发现不了。特别是海鲜市场,大部分卖的都是大容量的!很多网友就要问了,这种扩容机,用起来体验如何?会不会用着用着就坏了
别以为防晒仅仅是护肤,其实也是抗衰老高温天,除了防中暑,防晒也很重要。晒伤的危害可不仅仅是晒黑或脱皮,还有随之而来的各种光老化反应和光变态反应。从皮肤科角度来看,不仅仅女士,男士也要注意防晒。防晒,到底防的是什么?防
你是不是最近又长痘了?说到战痘史,我们都是一把辛酸泪,除了我们熟悉的激素痘之外,还有脸上不同部位突然出现的痘痘,它们的出现会让我们防不胜防,很是苦恼哦,今天我总结一下各个部位痘痘出现的原因和改善方式,快
浅浅的黄瓜诗,让我看到了什么?一个女诗人,平时生活富足,衣食无忧。闲暇时间太多,不知如何打发。精神世界极度贫乏,虚无,无思想,没信仰。靠一些低级欲望来满足自己。任由原始欲望吞噬自己。任由低级思想放飞。一会儿黄瓜
iPhone14到手要做的五件事iPhone14有很多小伙伴们马上就会拿到手了,新的iPhone到手一定要知道的五件事。1。苹果支持14天无理由退货,仅限于这三个渠道,其它渠道购买的机器,激活后并不支持无理由退货
施罗德化身德国英雄遭驱逐全场为他欢呼名记直呼他将得到新合同北京时间9月14日,男篮欧洲杯继续进行。在一场四分之一焦点之战中,德国队以10796击败希腊队,晋级本届欧洲杯4强。德国队能够击败拥有字母哥的希腊队,当家球星施罗德可谓是功不可没。
成品油运输行业专题研究全球成品油运的真正逻辑(报告出品方作者中信建投,韩军)一成品油种类丰富,柴油和汽油消费需求占比超50成品油(Productoil)大致可分为轻质馏分油(汽油石脑油等)中间馏分油(柴油航空煤油等)重质燃料
说说我接手快递店的坑,给想做的做个参考很多人都觉得开个快递店好赚钱,轻轻松松月薪上万。其实并不是这样的,极个别也能达到月入一万,但也都是汗水和泪水换的。快递店的收入是和你的付出成正比的,多劳多得。也有人觉得,快递店的工
浅谈如今现状最近,关于明星李某某嫖娼的新闻上了热搜,众多国民在媒体新闻下留言,多是调侃语气。他们笑他不懂得珍惜生活,关注于明星八卦这一块,一出新闻目光聚焦于某某,而不是某事,此状颇为堪忧。读者
克瓦拉茨赫利亚利物浦是欧洲最负盛名球队之一,但胜利已成过去直播吧9月12日讯接受每日纪录报记者采访时,那不勒斯攻击手克瓦拉茨赫利亚谈到了那不勒斯在欧冠中的表现,他表示战胜利物浦已成过去。克瓦拉茨赫利亚表示参加欧冠是每个人的梦想,现在说我们
网红湾湾再爆料李易峰嫖娼事件一共17人272张照片实锤今天下午,曾经写长文爆料薛之谦的网红李雨桐又发声了,这次她是为网红湾湾发声。李雨桐和湾湾是多年好友,2017年的时候,李雨桐和薛之谦事件中,湾湾曾为李雨桐发声,为她说话。李雨桐为胡
服贸会昌平区签下35亿元大单在服贸会北京日活动上,昌平现场签约3家企业2022年服贸会进入尾声,携重磅签约交易成果,昌平交易分团本次服贸会之旅完满收官。从三带汇聚未来之城的文旅板块北京日签约两区成果发布再到投
全球第一大雇主员工数是富士康的3倍,背后家族财富达1。65万亿衡量一个企业的规模,不仅仅是看它的产值,员工数量也是比较重要的考量因素。虽然与其所从事的行业有关,但整体来看,员工数量的变化在一定程度上与该企业的经营业绩直接相关。根据2022年财
夜读丨一季静秋,淡淡清愁。作者丨汐言主播丨莹丽亿番洛瓦秋天,是个不断沉淀的季节,繁华与凉薄之间,明艳的痕迹渐次隐退,自然风物愈加明朗而闲适。秋的心绪,越来越淡,秋的况味,越来越浓。秋是忧郁的,也是深情的。
关于理想这件大事儿中秋将至,月大如盘,抬头望月,总有美人兮在云端,这份来自少年时就有的执拗,好奇了后来的许多年于是基于后来的一念之差,于笔墨间谱写了一段佳话。告诉你们关于理想这件大事儿,即便远在飞云
一个人最大的愚蠢,活在别人的眼中哲学大师叔本华在人生的智慧中说过这样一句话我们人性中都有一特殊弱点,就是过分看重别人对自己的看法。细细想来,的确如此。很多时候,我们的痛苦与压力,并不是因为世事的艰辛,而是源于对他
贾浅浅清晨赏析清晨我们,一起在睡觉你起了一根竹竿我开了一朵莲花应广大网友要求,我终于对这首清晨下手了俗话说得好,一年之计在于春,一日之计在于晨清晨作为一天中最美好的时刻无疑是最值得思考和享受的有
掌舵7000亿集团,她成了中国新女首富天下网商章航英编辑吴羚玮市场正在加速洗牌。彭博亿万富翁实时指数显示,截至9月7日,恒力石化董事长范红卫以近107亿美元(约合人民币745亿元)身家成为新任中国女首富,位居全球富豪榜