前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >最近,我用pandas处理了一把大数据……

最近,我用pandas处理了一把大数据……

作者头像
luanhz
发布2020-10-26 15:08:18
1.3K0
发布2020-10-26 15:08:18
举报
文章被收录于专栏:小数志小数志

导读

pandas是python数据分析的不二选择,堪称瑞士军刀般的存在,几乎可以胜任数据分析的全过程。如果说有什么缺点的话,那么就是其不支持分布式,所以对于小数据量完全不压力,但面对大数据时却当真有些乏力。近日,自己便用pandas处理了一些大数据场景,现分享几个心得技巧。

首先简单介绍下场景:数据是每个月一份的csv文件,字段数目10个左右,单个文件记录数约6-8亿之间,单个文件体积50G+的样子。表中是一条条的带有时间字段的数据,需求是对数据进行汇总统计和简单分析处理(一般而言,数据量巨大的需求处理逻辑都不会特别复杂)。所以,虽然标题称之为大数据,但实际上也没有特别夸张。

01 大数据读取

pandas自带了常用文件的读取方法,例如csv文件对应的读取函数即为pd.read_csv,这也是日常应用中经常接触的方法。然而对于处理这个50G的csv文件而言,直接使用是肯定不行的,当前个人电脑内存普遍在8G-16G内存之间,笔者的是一台8G内存的工作机,除去系统占用基本留给用于加载数据的空间不到6G,另一方面通过多次试验结果:对于一个2G的文件,读取过程中内存占用会达到4G左右,大概是实际文件体积的两倍,加载完毕之后会有有所回落。所以,就8G内存的工作机而言,读取一个2.5G的大文件本身已经存在一定风险。

为此,pandas开发者专为此设计了两组很有用的参数,分别用于控制行和列信息:

  • skiprows + nrows,前者用于控制跳过多少行记录,后者用于控制读取行数,skiprows默认值为0,nrows缺省读取所有行数,这也是最常用的方式。但合理的设置两个参数,可以实现循环读取特定范围的记录
  • usecols:顾名思义,仅加载文件中特定的列字段,非常适用于列数很多而实际仅需其中部分字段的情况,要求输入的列名实际存在于表中

pd.read_csv()中相关参数说明

具体到实际需求,个人实现时首先通过循环控制skiprows参数来遍历整个大文件,每次读取后对文件再按天分割,同时仅选取其中需要的3个列字段作为加载数据,如此一来便实现了大表到小表的切分。虽然受限于内存而执行效率有限,但也终究算是一种解决方案。

02 内存管理

严格来说,这可能并不是大数据处理中才涉及到的问题,而是由Python的变量管理特性决定的。不同于C++中的手动回收、Java中的自动回收,Python中的对象采用引用计数管理,当计数为0时内存回收。所以,如果当一个变量不再需要使用时,最简单的办法是将其引用数-1,以加速其内存回收。有一定python基础的读者可能会想到用关键字del实现,这个思路是对的,但有时还不够保险和彻底,更为靠谱的方案是del + gc.collect()显式回收。这里gc是一个python内置模块,用于内存回收,gc = garbage collect。

仍然是循环读取大文件分表的问题,对于每次循环,读取一个大文件到内存,执行完相应处理流程后,显式执行以下两行代码即可,实测效果很有用。

代码语言:javascript
复制
del xx
gc.collect()

03 时间字段的处理

给定的大文件中,时间字段是一个包含年月日时分秒的字符串列,虽然在read_csv方法中自带了时间解析参数,但对于频繁多次应用时间列进行处理时,其实还有更好的方法:转为时间戳。

例如,在个人的实际处理中主要用到的操作包括:按时间排序、按固定周期进行重采样、分组聚合统计等,这几个操作中无一例外都涉及到时间列的比较,如果是字符串格式或者时间格式的时间列,那么在每次比较中实际要执行多次比较,而如果转换为时间戳后,则参与比较的实际上是一个整数值,毫无疑问这是效率最高的比较类型。进一步地,对于重采样需求而言,还可以通过整除特定的时间间隔,然后执行groupby操作即可。例如,执行每5分钟重采样,则可将所有时间戳(秒级)整除300,然后以相应结果作为groupby字段即可。

这里,补充两种将时间格式转换为时间戳的具体实现方法:

代码语言:javascript
复制
# 假设df['dt']列是时间格式,需将其转换为时间戳格式
# 方法一:
df['dt'] = (pd.to_datetime(df['dt'])-pd.to_datetime('1970-01-01T08:00:00')).total_seconds()

# 方法二:
df['dt'] = (pd.to_datetime(df['dt']).values - np.datetime64('1970-01-01T08:00:00Z')) // np.timedelta64(1, 's')
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-10-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小数志 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档