最近处理了一个ip地址段转换的问题,在用python转换完成后试了下数据分析框架pandas,果然速度快了不止一倍。
记录一下pandas处理cvs文件的用法。
源文件(170M)示例如下:
000.000.000.000,000.255.255.255,保留地址,保留地址,*,*,*,*
001.000.000.000,001.000.000.255,APNIC,APNIC,*,apnic.net,*,*
001.000.001.000,001.000.003.255,中国,福建,*,*,*,*
001.000.004.000,001.000.007.255,澳大利亚,维多利亚州,墨尔本,*,*,*
001.000.008.000,001.000.015.255,中国,广东,*,*,*,*
目标文件示例如下:
0000000000,0016777215,保留地址,保留地址,
0016777216,0016777471,APNIC,APNIC,
0016777472,0016778239,中国,福建,
0016778240,0016779263,澳大利亚,维多利亚州,墨尔本
0016779264,0016781311,中国,广东,
下面是普通处理:
# 标准ip地址转整数 def ip2dec(addr): # 将点分十进制IP地址转换成十进制整数 items = [int(x) for x in addr.split(".")] return sum([items[i] << [24, 16, 8, 0][i] for i in range(4)])i def ip2decStr(addr): return str(ip2dec(addr)).zfill(10) def saveFile(outfile, date): fl = open(outfile, 'w') fl.writelines(date) fl.close() def dealFile(infile, outfile): # lines = open(file) data = [] with open(infile) as lines: for line in lines: sep = ',' word = line.split(sep, 5) ipStart = ip2decStr(word[0]) ipStop = ip2decStr(word[1]) country = word[2] provice = word[3] if (word[4] == '*'): city = '' else: city = word[4] temp = ipStart+sep+ipStop+sep+country+sep+provice+sep+city+'\n' data.append(temp) saveFile(outfile, data) # lines.close() if __name__ == '__main__': startTime = datetime.datetime.now() dealFile('D:\\ipfile.txt', 'D:\\ipResult01.txt') stopTime = datetime.datetime.now() print((stopTime-startTime).microseconds)使用pandas处理:
# coding:utf-8 import datetime import pandas as pd # 标准ip地址转整数 def ip2dec(addr): # 将点分十进制IP地址转换成十进制整数 items = [int(x) for x in addr.split(".")] return sum([items[i] << [24, 16, 8, 0][i] for i in range(4)]) def ip2decStr(addr): return str(ip2dec(addr)).zfill(10) def converts(str): if str == '*': str='' return str if __name__ == '__main__': # 使用pandas读取文件数据 startTime = datetime.datetime.now() data = pd.read_csv('D:\\ipfile.txt', encoding='gbk', usecols=[0, 1, 2, 3, 4], header=None) data[0] = data[0].apply(lambda x: ip2decStr(x)) data[1] = data[1].apply(lambda x: ip2decStr(x)) data[4] = data[4].apply(lambda x: converts(x)) data.to_csv('D:\\ipResult02.csv', sep=',', index=False, header=None, encoding='gbk') stopTime = datetime.datetime.now() print((stopTime-startTime).microseconds)处理时间对比:
普通处理:900000微秒 VS pandas处理:618000微秒
PS:遇到的问题:
1、由于源文件是gbk格式,所以需要指定编码,否则默认编码为UTF-8
data = pd.read_csv('D:\\ipfile.txt', encoding='gbk', header=None)2、如上代码读取文件,由于文件不规范,某些行列数多导致报错:
pandas.errors.ParserError: Error tokenizing data. C error: Expected 8 fields in line 73, saw 10
由于业务只需要前5列数据所以作如下处理:
data = pd.read_csv('D:\\ipfile.txt', encoding='gbk', usecols=[0, 1, 2, 3, 4], header=None)