pandas 处理cvs格式文件

最近处理了一个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)

你可能感兴趣的:(python)