美文网首页python
python2.7处理大文件心得体会

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

作者: Chelsea_Dagger | 来源:发表于2017-12-01 21:51 被阅读260次

    最近关于毕业设计遇到了第一个小难题,那就是读取一个将近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处理大文件的一点小心得

    实在是很微小的心得

    相关文章

      网友评论

        本文标题:python2.7处理大文件心得体会

        本文链接:https://www.haomeiwen.com/subject/poybbxtx.html