最近在学习Python语言,正好有一个需求可以让我学习Python,这个需求我从刚开始完成其功能,最后到性能的优化,这当中体会到会写和写好的差距,从开始的一个867M的数据消耗时间2772s。到最后只要69s完成,当中巧妙的使用了很多知识点,今天就开始整理整理我是如何一步步做到的,其中又学到了哪些知识点,给大家分享。
业务需求:
Ø统计每个关键字的总词频,支持正则表达。例如:伤*
Ø不同类型的关键字在不同的文件中,即总共有80个文件,每个文件下含有多个关键字,
统计各关键字对应的词频,支持关键字搜索的文件是个目录
Ø由于分词的原因,支持关键字前后有“的”字参与计算,例如:高兴,在文本中“的高兴”、“高兴的”都需参与计算。
Ø统计文件的总词频,其中标点符号不参与计算
Ø统计文件的总记录数
Ø统计每个文件其关键字的总词频,即假设:sad.txt下有100个关键字,即100个关键字出现词频的总和
Ø生成一个总文件,含有:指标名、指标的总词频、文件出现的总词频、文件的总记录数
Ø出于性能考虑,支持管道,即统计的文件来自于hive查询的结果作为统计的输入文件。
实验环境:
操作系统环境:32个CPU,128G内存
测试数据:4266766条;867M文本
关键字:有80个关键字文件;总共12675个关键字
数据背景:
》数据在词频统计前,已经使用了python中的jieba模块分好词,各词中间使用了空格隔开
》字典目录中有80个文件,这里为了方便举2个例子看看字典的构成
伪码思路:
一、初始化字典目录
初始化字典目录中的80个文件的关键字,结果文件存放在以下3个列表中,列表构成如下:
》构建3个列表,file_dic=[]、file_list=[]、re_ke_dic=[]。
》file_dic=[]列表有80个元素(根据字典目录的个数决定),每个元素是一个字典,字典中
存放关键字对应词频数,初始化都为0,举例:[{’遗弃':0,'遗憾':0,‘错过':0,'默哀':0,'亏
损':0,'糟蹋':0,'怀念':0,'难过':0,’烂':0},{'大家':0,'吾人':0,'吾等':0,'我俩':0,'们':0,'咱':0,
'咱们':0}]
》file_list=[]列表跟file_dic=[]列表对应存放各关键字对应的文件名,['sad.txt','we.txt']
》re_ke_dic=[]列表也与file_dic=[]列表对应存放含有*的关键字字典(存放时*删除),
没有*的文件就是空字典。例如:[{'郁‘:0},{}]
伪码步骤:
1.第一层循环读字典目录中的80个文件
2.第2层循环读每个文件中的关键字
3.在2层循环中新建2个空字典将带*和不带*的关键字放进去,其value值为0
4.循环第2层结束(即一个文件结束),将3中的2个字典添加到file_dic、re_ke_dic列表中
5.并将第2步的文件名添加到列表file_list中
6.重复循环2-5的步骤直至字典目录中的文件读完
二、词频统计开始
不带*的关键字词频统计伪码:
1.第1层循环行读文件直至结束
2.行读的一行文件根据分隔符找到需要统计词频的字段
3.将取出的字段内容使用空格进行分割生成一个可迭代的对象
4.第2层循环3中的迭代对象,即循环的是每个词word
5.循环初始化好的列表file_dic,即循环了每个元素中的关键字字典
6.将第4步中的每个word在5中的每个字典中判断是否存在,存在就将file_dic列表字典
中对应的关键字的值加1
7.循环4-6步判断每行中的word是否存在
8.每行的word读完就循环下一行记录,即循环1-7步直至文件结束
9.在结束后即统计完了不带*的关键字出现的记录数
带*的关键字词频统计伪码:
10.循环了列表re_key_dic
11.将其关键字通过正则表达式中匹配,使用re.findall将匹配到生成的列表求长度,即使带*关键字的次数
12.将列表file_dic、re_key_dic中关键字及其value值通过file_list列表中的文件名新建文件循环写入到文件中
在python高性能词频统计历程----优化一:我是如何根据该版本优化其脚本,质的飞跃从2772s优化到119s