主要内容
本文主要结合最近一个项目,介绍python在进行大量数据清洗过程中的一个技巧,可以防止内存崩溃。
一、背景
1、项目过程要求处理一个包含260万条左右数据的excel表格,大约90M,自己电脑无法直接打开这个excel表格(相当慢)
2、excel表每条数据包含一个工作地地址字段,很乱,需要从中提取省市区县,这里用split、正则表达式都会有很多漏处理的数据,没少头疼
二、解决办法
1、针对excel无法打开的情况,直接使用pd.read_excel()读成dataframe进行查看
2、这里从不规则地址中提取省市区县找到了一个非常好用三方包,chinese_province_city_area_mapper,它采用了jieba分词工具,非常适用于这种不规则文本中提取行政区划等规则文本。另外,它的使用方式如下:
3、直接使用这个三方包对全部250万条数据进行处理会出现“memory error”问题。网上很多帖子提到出现这个问题有可能是python用的是32bit的,但这里不是这个原因,而是因为确实内存用光了,我亲眼看着任务管理器进程内存耗用一步步由绿变红到死机。以下是我的电脑配置:
我这里使用了“分批+垃圾回收”的机制,成功解决了问题,内存最多只用到1.7G,用时大概30—40分钟。
(1)分批:batch
思路来源于神经网络里模型训练用到的mini-batch gadient descent方法,确定一个合适的batch_size,每处理一部分,就将该部分append到dataframe中去,然后进行垃圾回收,接着进行下个循环。
需要注意的是:每个batch返回的temp(dataframe类型,通过cpca.transform()处理得到)在最终合并时index要重新设置,否则在后续处理时会出现multiple index的错误(比如:merge操作就会出现意想不到的结果)。
(2)垃圾回收
在网上查阅了许多资料,发现python 的gc.collect()可以进行垃圾回收,及时清除中间变量(指通过指针找不到的,这里要好好理解下,只有指针无法找到的变量,才会被当作垃圾清除)。所以采用了一个方法,先使用del方法删除变量,在进行gc.collect()回收,效果很好(注意使用del方法后并没有清除内存,只是断掉了指针,使之成为无效变量,还占用着内存)。
4、使用垃圾回收机制需要注意,这一操作会影响程序的执行效率,应尽可能地减少gc.collect()的次数
5、针对数据量很大的情况,一定要注意保存数据副本,即使保存数据变量空间,避免出现误操作后重新处理数据的情况
6、batch处理时,要注意设置断点(当前batch提醒,如果出错了,要知道是哪个地方出错的)
评论 (0)