您的位置:首页 > 编程语言 > Python开发

用python对文本格式的数据进行统计处理

2017-09-01 16:26 946 查看
来自今天遇到的问题。

示例数据集如下所示:

#test.txt

TE HE AP GE
A B C D
D A A D
B C D A
C C C C
D A A A
B A E F


其格式为:

第二行至最后一行为样本,第一行为样本特征,分别用代号(TE、HE、AP、GE)表示。

每个特征会有离散的几种不同的取值,本文的目的是为了统计每一种特征值在样本集中出现的频数。

对于数据规模很大的文件进行这种统计处理,会遇到的问题是,对于文件逐行进行处理很容易,但是当遇到这种对于列数据进行处理还需费点功夫。

我想到的第一个方法是将整个数据集读成二维数组(嵌套的List),然后用numpy中的transpose函数来行列变换,再交给Counter函数处理。经过一番折腾,找到了一个简单的方法拿出来分享一下:

首先使用csv模块来读取文本,可自动去除行末的换行符(’\r\n’)

dataFile = open('ts.txt','rb') #以read和binary的方式打开文件,csv必须加上'b'
dataTable = csv.reader(dataFile, delimiter=' ') #delimiter以空格来分割数据,类似split函数


经上述处理后,数据以列表的形式存储在了dataTable中

#dataTable是一个迭代器
for row in dataTable:
print row

#----输出为----
['TE', 'HE', 'AP', 'GE']
['A', 'B', 'C', 'D']
['D', 'A', 'A', 'D']
['B', 'C', 'D', 'A']
['C', 'C', 'C', 'C']
['D', 'A', 'A', 'A']
['B', 'A', 'E', 'F']


使用next的方法,提出第一行的表头

headList = dataTable.next() #表头以列表存在于headList中,执行后dataTable不再包含上面输出的第一行数据


zip函数用来产生元组

>>> lst_a = [1,2,3]
>>> lst_b = [4,5,6]
&
4000
gt;>> zip(lst_a, lst_b)
[(1, 4), (2, 5), (3, 6)]

>>> lst_c = [7,8,9,0]
>>> zip(lst_a, lst_b, lst_c)
[(1, 4, 7), (2, 5, 8), (3, 6, 9)]

>>> pack = (lst_a, lst_b, lst_c)
>>> zip(*pack)
[(1, 4, 7), (2, 5, 8), (3, 6, 9)]

>>> zip(*dataTable)
[('A', 'D', 'B', 'C', 'D', 'B'),
('B', 'A', 'C', 'C', 'A', 'A'),
('C', 'A', 'D', 'C', 'A', 'E'),
('D', 'D', 'A', 'C', 'A', 'F')]


行列变换

dataList = map(list, zip(*dataTable))
print dataList

#----输出为----
[['A', 'D', 'B', 'C', 'D', 'B'],
['B', 'A', 'C', 'C', 'A', 'A'],
['C', 'A', 'D', 'C', 'A', 'E'],
['D', 'D', 'A', 'C', 'A', 'F']]


注意此处的输出,嵌套在第二层的每一个列表中的数据是原数据集中每一列的数据。其中map()函数的作用可以见我的另一篇博客Python map,filter,reduce函数学习

Counter函数用来计数

>>> from collections import Counter
>>> Counter(['a', 'b', 'a', 'c'])
Counter({'a': 2, 'c': 1, 'b': 1})

>>> Counter("winter is coming")
Counter({'i': 3, ' ': 2, 'n': 2, 'c': 1, 'e': 1, 'g': 1, 'm': 1, 'o': 1, 's': 1, 'r': 1, 't': 1, 'w': 1})


再用Counter函数对每一列各个特征值进行统计

CounterTable = map(Counter, dataList)
print CounterTable

#----输出为----
[Counter({'B': 2, 'D': 2, 'A': 1, 'C': 1}),
Counter({'A': 3, 'C': 2, 'B': 1}),
Counter({'A': 2, 'C': 2, 'E': 1, 'D': 1}),
Counter({'A': 2, 'D': 2, 'C': 1, 'F': 1})]


至此统计结束,还可以将统计结果与特征名映射起来,保存在python字典中

Map = dict(zip(headList, CounterTable))


利用pickle模块将python字典(其实任何python数据类型均可导出)导出到文件中

with open('Mapdata.pkl', 'wb') as outputFile:
pickle.dump((Map, headList), outputFile)

#或者:

with open('Mapdata.pkl', 'wb') as outputFile:
pickle.dump(Map, outputFile)
pickle.dump(headList, outputFile)


在新文件中载入

with open('Mapdata.pkl', 'rb') as inputFile:
Map, headList = pickle.load(inputFile)

#或者:

with open('Mapdata.pkl', 'rb') as inputFile:
Map = pickle.load(inputFile)
headList = pickle.load(inputFile)


完整代码如下:

#-*-coding:utf-8-*-
from collections import Counter
import csv
import pickle
with open('ts.txt','rb') as dataFile: #文件处理
dataTable = csv.reader(dataFile, delimiter=' ')
headList = dataTable.next()
dataList = map(list, zip(*dataTable))
CounterTable = map(Counter, dataList)
Map = dict(zip(headList, CounterTable))

with open('Mapdata.pkl', 'wb') as outputFile: #以python数据格式存储到本地文件
pickle.dump(Map, outputFile)
pickle.dump(headList, outputFile)


从本地文件载入

#-*-coding:utf-8-*-
with open('Mapdata.pkl', 'rb') as inputFile:
Map = pickle.load(inputFile)
headList = pickle.load(inputFile)
print Map
print headList


最后说明:pickle模块的代码是我强行加入进去的,实际上以python的数据结构存储这些数据没有实际意义。夹带这点私活,是想起来了pickle的简单的用法,怕自己再忘记,记录下来。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐