大家好,欢迎来到IT知识分享网。
前言
之前遇到一篇很长很长的文档,需要统计一下某一个人物或者某一些词出现的次数,这种情况人力自然是不行。但是可以利用 python 来解决这个问题。例如:我们可以利用 python 统计出《哈姆雷特》或者是《红楼梦》中人物出场的频率。
首先用《哈姆雷特》试一下:
第一步:下载《哈姆雷特》英文版 TXT 文件
哈姆雷特英文版TXT文档下载:https://wwk.lanzoub.com/ipZg90ffa0lc
第二步:开始编写代码
txt = open("hamlet.txt", "r").read() # 打开文件 r 读权限
1.对打开后的文件进行预处理
for ch in '# $ % & () * + , - . : ; < = > ? @ [\\] ^ {}': txt = txt.replace(ch, "") # 文中的特殊字符用空格代替
2.文本分词
txt = txt.lower() # 将所有的字母转化为小写 words = txt.split() # 什么都不填表示用空格来分隔
这是英文文本,单词之间本身就存在空格符,所以是不需要分词的。这一步应该算是文本预处理。但是中文文本词与词之间没有空格符,所以需要使用中文分词工具,例如如下的第三方库:jieba、pkuseg、pynlpir、thulac 等等。
3.词频统计
这就有一个问题,这些词我们预处理已经完成,但是它们应该去哪里呢?
所以我们需要一个存放词的容器——没错,就是字典。因为我们要统计的结果是词+它出现的次数,所以可以看作是字典中键与值之间的关系。
所以,先定义一个存放词的空字典:
counts = {}
然后我们需要把预处理过的词都放入空字典。然后计算就可以了。
if word in counts: counts[word] = counts[word] + 1 else: counts[word] = 1
这样我们就能计算出词出现的次数了,但是这样不够简洁,我们还可以这样写:
for word in words: counts[word] = counts.get(word,0) +1
第二行中的 count[word]是把遍历到的词作为 key,后面的表达式,get 方法去查询 key 出现的次数,出现一次,就+1,如果没有,返回 0。这样,就可以了。
另外,词频统计会统计所有的词出现的次数,但是,我们有时候做分析或者是其他需要的结果中并不需要这么多的词,所以我们可以进一步完善一下代码。
excludes = {"the", "and", "of", "you", "a", "i", "my", "in"} for word in excludes: del(counts[word])
这样,我们就把一些冠词、连接词、介词一些我们不太需要的词都排除掉。依然是利用 for 循环去遍历文件中的词,并用 del 方法删去它们。
【上面的排词库可以随着程序的运行一步一步添加词汇,以达到打印对自己有意义的结果的目的】
至此,其实单单是统计词频的工作已经做完了,但是,我们得拿到这个结果,所以,我们定义一个空列表来存储它们。
items = list(counts.items()) print(items)
打印出来的结果会是这样:[(‘tragedy’, 3), …],列表中包含的是字典中所有键值对形成的元组。
emm…但是这个结果依然有点不尽人意。原因是这个结果是把字典中的键值形成的元组,保存到列表里面去,但是字典是无序的,打印出来的结果就仅仅只是一个结果,我们无法统计那个词频率最高,那个最低,当然,数据少了还可以,如果数据一多,拥有庞大数据的列表我们就无从下手了,所以,我们得实现排序。
4.结果排序(这里要用到 sort()和 lambda 函数)
items.sort(key=lambda x: x[1], reverse=True)
这样,就实现了以词出现的次数为条件的降序排序。sort()方法便是以第一列为基准升序排序的。但是我们用 lambda 这个匿名函数就可以了让它以第二列为基准降序排序。
5.输出排序后的结果
因为结果很多,尤其是大文件,我们会得到一个信息量很大的结果,不过呢,我们可以根据自己的需要打印排名前 10 或者前 20 的结果。
for i in range(10): word, count = items[i] print("{0:<10}{1:>5}".format(word, count))
源代码:
txt = open("hamlet.txt", "r").read() # 打开文件 r 读权限 for ch in '# $ % & () * + , - . : ; < = > ? @ [\\] ^ {}': txt = txt.replace(ch, "") # 文中的特殊字符用空格代替 txt = txt.lower() # 将所有的字母转化为小写 words = txt.split() # 什么都不填表示用空格来分隔 counts = {} for word in words: counts[word] = counts.get(word,0) +1 excludes = {"the", "and", "of", "you", "a", "i", "my", "in"} for word in excludes: del(counts[word]) items = list(counts.items()) items.sort(key=lambda x: x[1], reverse=True) for i in range(10): word, count = items[i] print("{0:<10}{1:>5}".format(word, count))
12.14日修改
有小伙伴私信说直接运行源代码会出错。是因为这一句:
words = txt.split() # 什么都不填表示用空格来分隔
这一句也是在的,在4行,但是在编辑的时候没有换行,已经改正。
原文在我的博客网站:www.myxfhome.top,欢迎大家访问
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/97800.html