Python入门——词频统计(瓦尔登湖)

本文详细介绍了如何在Python中对文本文件进行词频统计,包括处理中文路径、编码问题、使用count()函数和Counter对象提高效率,以及代码调试和优化过程中的经验分享。
摘要由CSDN通过智能技术生成

1、题目背景

        ·深入理解列表使用方法,对瓦尔登湖的文本做一个词频统计,下载地址:Walden.txt_免费高速下载|百度网盘-分享无限制,下载后使用Pycharm打开文本重新保存一次,这是为了避免编码的问题。

2、代码调试和调整

        ·1、直接使用count()函数进行词频统计

path = 'D:/Walden.txt'
with open(path,'r') as text:
    words = text.read().split()
    print(words)
    for word in words:
        print('{}--{} times'.format(word,words.count(word)))

报错结果:

·说明以及调试:

path = 'D:/Walden.txt'

一、path路径

1、path的路径是你存放Walden的地址,注意文件路径不要有中文字符,我就是因为C盘有中文字符所以将文件放在D盘的,小白的话直接复制文件地址即可

2、关于路径里面‘\’和‘/’的说明

        代码中处理文件路径时,使用斜杠(/)或反斜杠(\)作为目录分隔符的差异主要是由操作系统的不同导致的。不同的操作系统有不同的文件路径表示方式:

  • Windows 系统通常使用反斜杠(\)作为文件路径的分隔符。例如,C:\Users\Example\file.txt
  • Unix 基系统(包括Linux和macOS)使用斜杠(/)作为路径分隔符。例如,/Users/Example/file.txt

在Python和许多其他编程语言中,斜杠(/)被视为跨平台的路径分隔符,可以在不同的操作系统中使用,而不需要修改代码。Python解释器会根据运行的操作系统自动处理这些路径,使其能够正确地访问文件系统。

另一方面,当在Windows系统上直接使用反斜杠(\)时,需要注意转义字符的问题。在字符串中,\被用作转义字符的引导,如\n表示换行,\t表示制表符。因此,如果你想在Windows系统的Python代码中使用反斜杠作为路径分隔符,你需要使用双反斜杠(\\)来避免转义字符的意义,或者将字符串前加上r,表示原始字符串,如r"C:\Users\Example\file.txt"

总之一句话,在(Windows中)路径里面你可以写‘\\’或者'/'都可以

即:

path = 'D:/Walden.txt'

path = 'D:\\Walden.txt'

二、文件打开

with open(path,'r') as text:

·如果直接运行上述代码,在Windows下会报错,报错命令如下:

'gbk' codec can't decode byte 0xbf in position 2: illegal multibyte sequence

遇到 'gbk' codec can't decode byte 0xbf in position 2: illegal multibyte sequence 这类错误时,通常意味着你尝试以默认编码(在Windows上通常是GBK)打开一个不是以该编码保存的文件。对于英文文本文件,它很可能是以UTF-8编码保存的,特别是如果它包含了任何非ASCII字符。

解决办法是:通过指定正确的编码格式来解决这个问题。如果你的文件是以UTF-8编码的,你可以在open函数中指定encoding='utf-8'。即将第二行代码改为:

with open(path,'r',encodeing = 'utf-8') as text:

三、完整代码

path = 'D:\\Walden.txt'
with open(path,'r',encoding='utf-8') as text:
    words = text.read().split()
    print(words)
    for word in words:
        print('{}--{} times'.format(word,words.count(word)))

·运行结果部分截图:

仔细观察有以下问题:

1.有一些带标点符号的单词被单独统计了次数

2.有些单词不止一次地展示了出现的次数

3.由于python对大小写敏感,开头大写的单词被单独统计了

·2、调整统计方法,对单词做预处理

        一、解决方案:

                1.有一些带标点符号的单词被单独统计了次数——使用strip()函数去掉单词前后的标点符号,string.punctuation是一个字符串,包含了所有的标点符号,即strip(string.punctuation)去除一个单词里面出现的所有标点符号。

                2.有些单词不止一次地展示了出现的次数——使用set()集合去掉重复出现的单词

                3.由于python对大小写敏感,开头大写的单词被单独统计了——使用lower()函数将单词全部转化成小写,与第一个解决方法结合起来,可以写成:

                

word.strip(string.punctuation).lower() #word是你要进行处理的字符串

二、完整代码1.0版(适用于小型文本和日常文本)

import string

path = 'D:/Walden.txt'

with open(path,'r',encoding='utf-8') as text:
    words = [raw_word.strip(string.punctuation).lower() for raw_word in text.read().split()]
    words_index = set(words)
    counts_dict = {index:words.count(index) for index in words_index}

for word in sorted(counts_dict,key=lambda x:counts_dict[x],reverse=True):
    print('{}--{} times'.format(word,counts_dict[word]))

运行结果截图:

·说明:在运行这个代码过程中,你会发现他有很多for循环,所以运行之后需要一段时间才会给出运行结果,试想如果这个文本是超大文本,那运行的时间会呈指数式增长。(为2.0版本做铺垫)

代码解析:

  1. 导入string模块:这一步导入Python的string模块,以便使用string.punctuation获取所有的标点符号。

  2. 打开文件:使用with open(path,'r',encoding='utf-8') as text打开文件。这里指定了文件路径、读取模式('r'表示读取)、和文件编码('utf-8')。with语句确保文件在操作完成后会被正确关闭。

  3. 处理单词:通过列表推导式读取文件中的所有单词,去除每个单词前后的标点符号,然后转换为小写。这一步是为了统一单词的格式,便于后续的统计。

  4. 创建索引集合words_index = set(words)创建了一个包含所有唯一单词的集合。使用集合是因为集合中的元素是唯一的,这样可以确保每个单词只被统计一次。

  5. 统计单词出现次数counts_dict = {index:words.count(index) for index in words_index}通过字典推导式为每个唯一单词计算出现次数,并存储在counts_dict中。这里words.count(index)是一个相对低效的操作,因为它会对整个单词列表进行遍历来计算每个单词的出现次数。

  6. 打印结果:最后,通过一个for循环遍历counts_dict,并使用sorted函数按单词出现次数降序排序单词。lambda x: counts_dict[x]是一个匿名函数,用于指定排序的依据(即单词出现的次数)。然后,使用print语句打印每个单词及其出现次数。

·三、完整代码2.0版(适用于大型文本)

·3.1、问题重述:

        完整代码1.0版有效地统计了文本文件中每个单词的出现次数,并按出现频率从高到低打印结果。不过,如之前所述,使用words.count(index)进行计数是效率较低的,特别是对于较大的文本文件。一个更高效的方法是使用collections.Counter对象,它可以直接从单词列表生成单词计数的字典,避免了多次遍历整个单词列表的需要。

·3.2、代码块:
import string
from collections import Counter

path = 'D:/Walden.txt'

with open(path, 'r', encoding='utf-8') as text:
    # 使用列表推导式处理单词,去除标点符号并转换为小写
    words = [raw_word.strip(string.punctuation).lower() for raw_word in text.read().split()]
    # 使用Counter计算每个单词的出现次数
    word_counts = Counter(words)

# 按照单词出现次数降序排序并打印
for word, count in word_counts.most_common():
    print(f'{word}--{count} times')  #f-strings(引入于Python 3.6),f在字符串开始前表示这是一

                                                                            个格式化字符串。

·运行结果截图:

        

·解析说明:

        ·在这个修改后的版本中,我们使用Counter(words)直接从处理后的单词列表words中创建了一个Counter对象word_countsCounter对象是一个字典,其中的键是单词,值是对应的出现次数。

  ·Counter类的most_common()方法返回一个列表,其中包含了所有单词及其出现次数,按照次数降序排序。这样我们就可以直接遍历这个列表,并打印每个单词及其出现次数,而不需要手动排序。

        ·

`这种方法不仅代码更简洁,而且运行效率更高,特别是对于大型文本文件。

·也可以看出Python代码的优点在于丰富的库,可以极大简化运行时间和代码,提高运行速度。

3、总结

        ·编写代码的过程不是一蹴而就得,在之前的写代码过程中我总是想一遍就把代码的全部功能写出来,但是在看了很多入门书籍之后,我发现很多大型的编程文件都是先搭建一个框架,先实现基本功能,然后根据基本功能进行拓展和细化,以及根据代码出现的问题进行调试,然后逐步完善的,其实这个过程就是学习的过程,总有人想着一劳永逸,但是我相信一步步完善代码的过程才是编程的精髓吧。

  • 33
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值