利用python处理两千万条数据的一些经验(仅供自己记录)

5.3老板交给我一个任务,简单处理一些数据,三个CSV文件,每个都是2.3G大小,以下是要求


看着觉得很easy,兴冲冲地去搞了,当时还是用的notepad++写python代码,对于python来说,表里面的要求利用分片,替换等都可以完成,只剩下最后的滤重比较麻烦,想来想去,用了最笨的方法,遍历,还是两重的,时间复杂度瞬间飙到了n平方,代码跑了一晚上,还没跑出结果,于是放弃这个蠢办法,查了查数据清洗常用工具,发现有excel,于是尝试用excel解决问题,先根据需要滤重的三个属性进行排序,之后根据三个属性上下相邻的两个两行是否相同添加了新的一列,有重复则赋值TRUE,没有则赋值FALSE,保存之后,再利用python读取处理,凡是TRUE的直接略过,只处理FALSE的,自以为很聪明的解决了问题,结果发给老板,后来想起来打开excel的时候提示我“可能会损失部分数据”,而且查到了excel现在只能显示1048567条数据,所以想看看到底丢了多少条,用python读取之后,发现原文件有近两千万条数据,而我只处理了104万条,周末就上网查了很多资料,python的pandas库适合用来做数据处理,用import导入pandas库失败之后,下载安装了Anaconda,搭好环境之后(详情请见:https://www.zhihu.com/question/58033789)

按照正常思路,肯定是先去重再处理(去重可以去掉一半多数据),我将去重分成两步,先将所有属性全相同的去重之后再按照指定属性去重,然后按照要求对每一行数据进行处理,最后写出,后来看了pandas库的用法,里面的DataFrame有列名,而我的原始数据没有列名,所以我先将原始文件利用python的读取CSV文件读出来,判断是否是“脏”数据之后,存入一个list里(rows=[]),写入目标文件时,先将列名写入,然后将list写入,后来发现每次运行这个程序,电脑就卡死,清理了半天电脑之后发现还是如此,后来意识到可能是因为数据量太大,rows占了太多内存导致电脑卡死,所以想到了办法:先打开目标文件,写入列名,再打开原始文件,按行读取,按照条件判断这一行是否为“脏”数据,不是的话再按照上面表格里的要求进行处理,之后按行写入目标文件,这样一来,电脑内存占用率下降,电脑也就不会卡了,最后再将初步处理过的文件利用pandas打开,利用其中的DataFrame数据结构的方法进行去重,两千万条的数据五分钟之内处理完成,以下为源代码:

import csv
rows=[]
with open(r'C:\Users\Hanju\Desktop\uploadPortal(5).csv',"w", newline='') as _csvfile: 
    writer = csv.writer(_csvfile)
    #先写入columns_name
    writer.writerow(["Dev_mac","Action","User_mac","User_mac_head","Bssid","WiFi","Time","Date"])
    i=0
    with open(r'D:\UploadPortalData\uploadPortal (5).csv',encoding='UTF-8') as csvfile:
        readCSV=csv.reader(csvfile,delimiter=',')
        for row in readCSV:
            if(len(row)!=8):
                continue
            row1=[]
            i+=1
            row1.append(row[0].replace(':','')[-5:])
                
            if row[2]=='auth':
                row1.append('1')
            elif row[2]=='deauth':
                row1.append('2')
            elif row[2]=='portal':
                row1.append('3')
            elif row[2]=='portalauth':
                row1.append('4')

            row1.append(str(row[3].replace(':','')))
            row1.append(str(row[3].replace(':','')[0:6]))

            if row[0]==row[4]:
                row1.append('2')
            else:
                row1.append('5')

            if 'City-WiFi-5G' in row[5]:
                row1.append('2')
            elif 'City-WiFi' in row[5]:
                row1.append('1')
            else:
                row1.append('0')
        
            row1.append(float(row[6])/86400.0-2.0/3.0+719530.0)
            
            row1.append(row[7])
                
            writer.writerow(row1)

print('Done')
print(i)

import pandas as pd
df=pd.read_csv(r'C:\Users\Hanju\Desktop\uploadPortal(5).csv')
#print(df.head())
#print(df.tail())
print(df.shape)
New_df=df.drop_duplicates(['Action','User_mac','Time'])
print(New_df.shape)
#print(New_df.head())
#print(New_df.tail())
New_df.to_csv(r'C:\Users\Hanju\Desktop\uploadPortal(5)_Final.csv')
print('Done')

为了查看去重效果,加了几个输出

在这挖一个坑,其实还是应该先去重再处理会更省时间,但是目前还没有想到更好的办法,以后想到了再来更新,还是要再看看pandas库,实在太强大,不得不服

下面贴一部分原始数据:

F0:AC:D7:73:11:EC,d93004d3-2164-44a0-b4fc-f5adfcf56207,portal,3C:A3:48:45:EA:5E,F0:AC:D7:73:11:EC,City-WiFi,1524813532,20180427

F0:AC:D7:73:11:EC,d93004d3-2164-44a0-b4fc-f5adfcf56207,portal,3C:A3:48:45:EA:5E,F0:AC:D7:73:11:EC,City-WiFi,1524813532,20180427
F0:AC:D7:73:11:EC,d93004d3-2164-44a0-b4fc-f5adfcf56207,portal,3C:A3:48:45:EA:5E,F0:AC:D7:73:11:EC,City-WiFi,1524813532,20180427
F0:AC:D7:73:11:EC,d93004d3-2164-44a0-b4fc-f5adfcf56207,portal,3C:A3:48:45:EA:5E,F0:AC:D7:73:11:EC,City-WiFi,1524813532,20180427
F0:AC:D7:73:11:EC,d93004d3-2164-44a0-b4fc-f5adfcf56207,portal,3C:A3:48:45:EA:5E,F0:AC:D7:73:11:EC,City-WiFi,1524813532,20180427

这是处理后的部分数据:

,Dev_mac,Action,User_mac,User_mac_head,Bssid,WiFi,Time,Date
0,311EC,3,3CA34845EA5E,3CA348,2,1,737177.6381018519,20180427
17,311EC,1,F42981BEF089,F42981,2,1,737177.6349074075,20180427
18,311EC,2,F42981BEF089,F42981,2,1,737177.6349074075,20180427
19,311EC,1,F42981BEF089,F42981,2,1,737177.6349189816,20180427
20,311EC,1,3CA34845EA5E,3CA348,2,1,737177.6349421295,20180427

就用这个不算完善的结果来作为我CSDN博客的处女作吧,毕竟,终于动手写了一篇,虽然都是流水账,可能对别人没有多大参考价值,以后的博客多写一些遇到的坑及解决办法吧,做些记录的同时也有可能对别人有所帮助,毕竟我自己遇到的好多问题都是参考了很多博主的文章得以解决的,就到这里吧!

没有更多推荐了,返回首页