python2.7处理大文件心得体会

最近关于毕业设计遇到了第一个小难题,那就是读取一个将近1G的文件,并对其进行数据预处理工作。
意图是将数据打散,对于每个mac地址对其分配对应的时间戳和地点id(第二列)

数据集长这样:

2017/8/28 23:37:00,14,84742aa602e4
2017/8/29 04:38:00,13,000000000000
2017/8/29 04:46:00,13,000000000000
2017/8/29 04:47:00,13,000000000000
2017/8/29 05:16:00,13,84742ab11871
2017/8/29 05:17:00,13,84742ab11871
2017/8/29 05:18:00,13,b0e235c0398a,84742ab11871
2017/8/29 05:19:00,13,b0e235c0398a,84742ab11871
2017/8/29 05:20:00,13,b0e235c0398a,84742ab11871
2017/8/29 05:21:00,13,b0e235c0398a,84742ab11871
2017/8/29 05:22:00,13,b0e235c0398a,84742ab11871
2017/8/29 05:23:00,13,b0e235c0398a,84742ab11871
2017/8/29 05:24:00,13,b0e235c0398a,84742ab11871
2017/8/29 05:25:00,13,b0e235c0398a,84742ab11871
2017/8/29 05:26:00,13,b0e235c0398a
2017/8/29 05:27:00,13,b0e235c0398a
2017/8/29 06:53:00,18,84742aac34d7
2017/8/29 06:54:00,18,84742aac34d7
2017/8/29 06:55:00,18,84742aac34d7
2017/8/29 07:10:00,13,84742ab11871
2017/8/29 07:11:00,12,742344af2efd
2017/8/29 07:11:00,13,84742ab11871
2017/8/29 07:12:00,12,742344af2efd
2017/8/29 07:12:00,13,84742ab11871
2017/8/29 07:12:00,18,84742aac34f3
2017/8/29 07:13:00,12,742344af2efd,acc1eef136c1
2017/8/29 07:13:00,13,84742ab11871
2017/8/29 07:13:00,18,000000000000,84742aac34f3
2017/8/29 07:14:00,12,a4717460508e,742344af2efd,acc1eef136c1
2017/8/29 07:14:00,13,84742ab11871
2017/8/29 07:14:00,18,84742aac34f3,000000000000
2017/8/29 07:15:00,12,a4717460508e,742344af2efd,a8c83abd75f6,acc1eef136c1
2017/8/29 07:15:00,13,84742ab11871
2017/8/29 07:15:00,18,000000000000,84742aac34f3
2017/8/29 07:16:00,12,a4717460508e,742344af2efd,a8c83abd75f6,acc1eef136c1
2017/8/29 07:16:00,13,84742ab11871
2017/8/29 07:16:00,18,84742aac34f3,000000000000
2017/8/29 07:17:00,12,a4717460508e,742344af2efd,a8c83abd75f6,acc1eef136c1
2017/8/29 07:17:00,13,84742ab11871
2017/8/29 07:17:00,18,000000000000,84742aac34f3
2017/8/29 07:18:00,12,a4717460508e,acc1eef136c1,a8c83abd75f6
2017/8/29 07:18:00,13,84742ab11871
2017/8/29 07:18:00,18,84742aac34f3,000000000000
2017/8/29 07:19:00,12,a4717460508e,acc1eef136c1,a8c83abd75f6
2017/8/29 07:19:00,18,84742aac34f3,000000000000
......

现在准备对以上数据进行预处理,规整后的数据集:

2017/8/28 23:37:00,14,84742aa602e4
2017/8/28 23:38:00,14,84742aa602e4
2017/8/28 23:39:00,14,84742aa602e4
2017/8/28 23:40:00,14,84742aa602e4
2017/8/28 23:41:00,14,84742aa602e4
2017/8/28 23:42:00,14,84742aa602e4
2017/8/28 23:43:00,14,84742aa602e4
2017/8/28 23:44:00,14,84742aa602e4
2017/8/29 04:38:00,13,000000000000
2017/8/29 04:39:00,13,000000000000
2017/8/29 04:40:00,13,000000000000
2017/8/29 04:41:00,13,000000000000
2017/8/29 04:42:00,13,000000000000
2017/8/29 04:43:00,13,000000000000
2017/8/29 04:44:00,13,000000000000
2017/8/29 04:45:00,13,000000000000
2017/8/29 04:46:00,13,000000000000
2017/8/29 04:47:00,13,000000000000
2017/8/29 05:16:00,13,84742ab11871
2017/8/29 05:17:00,13,84742ab11871
2017/8/29 05:18:00,13,b0e235c0398a
2017/8/29 05:18:00,13,84742ab11871
2017/8/29 05:19:00,13,b0e235c0398a
2017/8/29 05:19:00,13,84742ab11871
2017/8/29 05:20:00,13,b0e235c0398a
2017/8/29 05:20:00,13,84742ab11871
2017/8/29 05:21:00,13,b0e235c0398a
2017/8/29 05:21:00,13,84742ab11871
2017/8/29 05:22:00,13,b0e235c0398a
2017/8/29 05:22:00,13,84742ab11871
2017/8/29 05:23:00,13,b0e235c0398a
2017/8/29 05:23:00,13,84742ab11871
2017/8/29 05:24:00,13,b0e235c0398a
2017/8/29 05:24:00,13,84742ab11871
2017/8/29 05:25:00,13,b0e235c0398a
2017/8/29 05:25:00,13,84742ab11871
2017/8/29 05:26:00,13,b0e235c0398a
2017/8/29 05:27:00,13,b0e235c0398a
2017/8/29 06:53:00,18,84742aac34d7
2017/8/29 06:54:00,18,84742aac34d7


之所以要这样处理源数据,是因为规整后的数据易于group,方便统计学操作,充分挖掘每个mac地址的数据信息。

以下列出三种文件处理的python代码,都是力求减少系统内存,其中以第三种方式处理大文件最为有效。

代码1:

理论上来说,总体上file.readlines()可以(取决于实现)不慢于你自己手动的一次次调用file.readline(),因为前者的循环在C语言层面,而你的循环是在Python语言层面。但是在内存占用上前者可能是后者的好几十百倍,因为前者会一次性把所有数据读取到内存中,而后者只每次读取一行。更好的写法是:

with open('filename') as file:
    for line in file:
        do_things(line)
# -*- coding: UTF-8 -*-

import csv
import numpy as np
import pandas as pd
from pandas import Series,DataFrame

# csv_reader = csv.reader(open('./macdata/origin_info.csv'))


new_line =[]
with open('./macdata/origin_info.csv') as file:



    for line in file:
        # print line.split(',')[0]
        # print len(line)
        # print len(line.split(','))
        line = line.split(',')
        line[2] = line[2].strip('\n')
        if len(line) ==0:
            continue
        if len(line)==3:
            new_line.append(line)
        if len(line) >3:
            for i in xrange(2,len(line)):
                new_line.append([line[0], line[1] , line[i].strip('\n')])

file=open('./macdata/normal_origin_info.txt','w')
file.write(str(new_line))
file.close()

# df = DataFrame(new_line)
# print df

代码2

使用python linecache

在python中,有个好用的模块linecache,该模块允许从任何文件里得到任何的行,并且使用缓存进行优化,常见的情况是从单个文件读取多行。

linecache.getlines(filename) 从名为filename的文件中得到全部内容,输出为列表格式,以文件每行为列表中的一个元素,并以linenum-1为元素在列表中的位置存储

linecache.getline(filename,lineno) 从名为filename的文件中得到第lineno行。这个函数从不会抛出一个异常–产生错误时它将返回”(换行符将包含在找到的行里)。
如果文件没有找到,这个函数将会在sys.path搜索。

linecache.clearcache() 清除缓存。如果你不再需要先前从getline()中得到的行

linecache.checkcache(filename) 检查缓存的有效性。如果在缓存中的文件在硬盘上发生了变化,并且你需要更新版本,使用这个函数。如果省略filename,将检查缓存里的所有条目。

linecache.updatecache(filename) 更新文件名为filename的缓存。如果filename文件更新了,使用这个函数可以更新linecache.getlines(filename)返回的列表。

# -*- coding: UTF-8 -*-

import csv
import numpy as np
import pandas as pd
from pandas import Series,DataFrame

import linecache

new_line=[]
file = linecache.getlines('./macdata/origin_info.csv')

for line in file:

    line = line.split(',')
    line[2] = line[2].strip('\n')
    if len(line) == 0:
        continue
    if len(line) == 3:
        new_line.append(line)
    if len(line) > 3:
        for i in xrange(2, len(line)):
            new_line.append([line[0], line[1], line[i].strip('\n')])


file=open('./macdata/normal_origin_info.txt','w')
file.write(str(new_line))
file.close()

不幸的是,以上两种代码最终都把主机内存跑爆炸了(TAT、
反省了一下,不是说withopen和linecache不好,而是new_line变量的创建过程过于消耗内存,因此第三种方法里,我选择每读取一行,便写一行到新文件中去,这样就解决了内存爆炸的问题
在这里含泪介绍方法三(自己摸索出来的(。

代码3

# -*- coding: UTF-8 -*-

import csv
import numpy as np
import pandas as pd
from pandas import Series, DataFrame

# csv_reader = csv.reader(open('./macdata/origin_info.csv'))
rs = open('./macdata/normal_origin_info.txt', 'w')

with open('./macdata/origin_info.csv') as file:
    for line in file:
        # print line.split(',')[0]
        # print len(line)
        # print len(line.split(','))
        line = line.split(',')

        if len(line) == 0:
            continue
        if len(line) == 3:
            # line[2] = line[2].strip('\n')
            rs.write(str(line[0]) + ',' + str(line[1]) + ',' + str(line[2].strip('\n')) + '\n')
            # rs.write(str(line)+'\n')
            # new_line.append(line)
        if len(line) > 3:
            for i in xrange(2, len(line)):
                rs.write(str(line[0]) + ',' + str(line[1]) + ',' + str(line[i].strip('\n')) + '\n')

rs.close()

以上就是关于python处理大文件的一点小心得

实在是很微小的心得

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,047评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,807评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,501评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,839评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,951评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,117评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,188评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,929评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,372评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,679评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,837评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,536评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,168评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,886评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,129评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,665评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,739评论 2 351

推荐阅读更多精彩内容

  • 一、温故而知新 1. 内存不够怎么办 内存简单分配策略的问题地址空间不隔离内存使用效率低程序运行的地址不确定 关于...
    SeanCST阅读 7,787评论 0 27
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,885评论 25 707
  • 春天,这个城市还是一如既往的阴冷多雨。瑟缩在被窝中手不停地划着手机屏幕,其实不管是什么新闻讯息又或者什么明...
    寒塘1840阅读 281评论 0 1
  • 为啥用简书? 身边有个每天撒鸡汤的上进男青年,叫他小五吧!毕业未满一年,激情还未退却。每天坚持健身、写作,并用简...
    一本丸子东阅读 257评论 2 0
  • 我今天阅读了《再被狐狸骗一次》77页到100页
    汪小霖阅读 204评论 0 0