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这是处理后的部分数据:
,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
联系客服