
本文详细介绍了如何使用python的`collections.counter`模块精确统计文本中特定关键词的出现次数。通过实例演示了文本预处理、生成词频计数器、查询单个文本中关键词频率以及分析两个文本间共有词汇的方法。文章强调了`counter`在词频统计中的高效性和准确性,并提供了优化现有代码的实践建议,旨在帮助读者掌握更专业的文本数据分析技巧。
在处理文本数据时,我们经常面临需要统计特定词汇在大量文本中出现频率的需求。例如,在一个合同文档集合中,我们可能需要找出某个关键词(如“违约”、“赔偿”)总共出现了多少次。传统的做法,如仅仅通过检查词汇是否存在于一个集合中,只能判断词汇的“有无”,却无法提供其“数量”,这往往是导致统计不准确的常见误区。本教程将深入探讨如何利用Python标准库中的collections.Counter工具,高效且准确地完成这一任务。
collections.Counter 是 Python collections 模块提供的一个强大的工具,它是一个 dict 的子类,专门用于计数可哈希对象。当给定一个列表、元组或字符串时,Counter 会自动统计其中每个元素的出现次数,并以字典的形式存储,键为元素,值为其计数。这使得它成为词频统计的理想选择。
要准确统计词汇,首先需要对原始文本进行适当的预处理,包括将所有文本转换为小写以忽略大小写差异,并移除标点符号、数字等非词汇字符。
以下示例演示了如何从网页获取文本,并对其进行清洗,以便后续的词频统计。
立即学习“Python免费学习笔记(深入)”;
import requests
import re
from collections import Counter
from bs4 import BeautifulSoup
# 示例:从维基百科页面获取文本
url_a = 'https://en.wikipedia.org/wiki/Leonhard_Euler'
url_b = 'https://en.wikipedia.org/wiki/Carl_Friedrich_Gauss'
# 使用BeautifulSoup从网页内容中提取纯文本
txt_a = BeautifulSoup(requests.get(url_a).content, 'html.parser').get_text()
txt_b = BeautifulSoup(requests.get(url_b).content, 'html.parser').get_text()
# 清洗文本:转换为小写,并使用正则表达式按非字母数字字符分割,得到词汇列表
# re.split(r'\W+', text) 会将文本按所有非字母数字字符分割,包括空格、标点等
cleaned_words_a = re.split(r'\W+', txt_a.lower())
cleaned_words_b = re.split(r'\W+', txt_b.lower())
print(f"文本A清洗后的前20个词: {cleaned_words_a[:20]}")
print(f"文本B清洗后的前20个词: {cleaned_words_b[:20]}")有了清洗后的词汇列表,我们就可以轻松地使用 Counter 来生成词频计数器。
# 为每个文本创建词频计数器
cnt_a = Counter(cleaned_words_a)
cnt_b = Counter(cleaned_words_b)
# 打印文本A中出现频率最高的10个词
print("\n文本A中出现频率最高的10个词:")
print(cnt_a.most_common(10))
# 打印文本B中出现频率最高的10个词
print("\n文本B中出现频率最高的10个词:")
print(cnt_b.most_common(10))Counter 对象生成后,我们可以非常灵活地查询特定词汇的计数。
这直接解决了原问题中“统计关键词在合同文件中出现次数”的需求。我们可以定义一个关键词列表,然后从已生成的 Counter 对象中查询这些词的计数。
# 定义一个关键词集合
keyword_list_words = {'mathematical', 'equation', 'theorem', 'university', 'integral', 'basel'}
# 统计关键词在文本A中的出现次数
# 使用 .get(word, 0) 可以安全地获取词汇计数,如果词汇不存在则返回0
keyword_counts_a = {word: cnt_a.get(word, 0) for word in keyword_list_words}
print(f"\n关键词在文本A中的出现次数: {keyword_counts_a}")
# 统计关键词在文本B中的出现次数
keyword_counts_b = {word: cnt_b.get(word, 0) for word in keyword_list_words}
print(f"关键词在文本B中的出现次数: {keyword_counts_b}")Counter 对象还支持集合操作,例如交集 (&),这使得找出两个文本的共有词汇变得非常简单。我们可以进一步获取这些共有词汇在各自文本中的具体计数。
# 找出两个文本共有的词汇(通过Counter的集合交集操作)
# cnt_a & cnt_b 会返回一个新的Counter,其中包含两个Counter共有的词汇及其在两者中最小的计数
# 为了获取各自的计数,我们需要遍历交集
common_words_set = cnt_a.keys() & cnt_b.keys()
# 获取共有词汇在两个文本中的具体计数,并按总计数降序排列
common_words_detailed = dict(sorted({
k: (cnt_a[k], cnt_b[k]) for k in common_words_set
}.items(), key=lambda kv: sum(kv[1]), reverse=True))
print(f"\n两个文本的共有词汇及其计数(按总计数降序):")
# 仅打印前15个共有词汇
for i, (word, counts) in enumerate(common_words_detailed.items()):
if i >= 15:
break
print(f"'{word}': (文本A: {counts[0]}, 文本B: {counts[1]})")回到最初的问题,如果我们的目标是统计一个关键词列表在多个合同类型文件中的总出现次数,并希望每次找到关键词时都递增计数,那么使用 Counter 可以极大地简化和优化代码。
假设我们有以下模拟数据:
# 模拟数据
# 假设 contract_type_files 已经包含了所有合同类型及其对应的词汇列表(已清洗)
# 注意:这里我们使用列表而不是集合,因为Counter需要统计重复项
contract_type_files = {
"合同A": ["apple", "banana", "apple", "orange", "apple", "contract", "term"],
"合同B": ["banana", "grape", "apple", "banana", "term", "condition"],
"合同C": ["kiwi", "apple", "orange", "term"]
}
keyword_list_words_example = {"apple", "banana", "term", "kiwi", "warranty"}
# 使用 Counter 来累积所有合同中关键词的总出现次数
final_common_word_counts = Counter()
print("\n--- 优化后的关键词统计过程 ---")
for contract_identifier, words_list in contract_type_files.items():
print(f"正在处理合同类型: {contract_identifier}")
# 为当前合同类型创建词频计数器
contract_word_counter = Counter(words_list)
# 遍历关键词列表,查询它们在当前合同中的出现次数
for keyword in keyword_list_words_example:
# 如果关键词存在于当前合同中,则获取其准确计数并累加到总计数器
# contract_word_counter[keyword] 会直接返回计数,如果不存在则返回0
final_common_word_counts[keyword] += contract_word_counter[keyword]
print(f"\n所有合同中关键词的总出现次数: {final_common_word_counts}")
# 原始代码的逻辑(如果只是检查存在性)
# common_words_dict = Counter() # 即使这里是Counter,原始逻辑也只计数一次
# for contract_type_identifier in contract_type_files:
# # 假设 words_for_contract_type 是一个集合,只包含不重复的词
# words_for_contract_type = set(contract_type_files.get(contract_type_identifier, []))
# for word in keyword_list_words_example:
# if word in words_for_contract_type:
# # 这里的 += 1 只能保证每个合同中每个关键词最多被计数一次
# # 无法统计同一个关键词在一个合同中出现多次的情况
# common_words_dict[word] += 1
# print(f"\n原始逻辑(如果只计数存在性)的结果: {common_words_dict}") # 结果会与期望不符通过上述优化,我们不再需要手动检查词汇是否存在于字典中并初始化计数,Counter 自动处理了这些细节,并且 contract_word_counter[keyword] 会直接返回该关键词在当前合同中的准确出现次数,而不是简单地判断其是否存在。
# 过滤空字符串的示例 cleaned_words_filtered = [word for word in cleaned_words_a if word] cnt_a_filtered = Counter(cleaned_words_filtered)
collections.Counter 是 Python 中进行词频统计的强大且高效的工具。通过首先对文本进行适当的预处理,然后利用 Counter 快速生成词频分布,我们可以轻松地统计特定关键词的出现次数,甚至分析不同文本间的共有词汇。掌握这一工具不仅能帮助我们解决常见的文本分析问题,还能显著提高代码的简洁性和执行效率。
以上就是Python教程:高效统计文本中特定关键词的出现次数的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号