Python数据分组与词频统计:从基础字典到Counter的高效实践
本文详解Python中数据分组的多种实现方式。通过对比手动构建字典、使用setdefault方法以及collections模块中的defaultdict和Counter类,展示如何优雅地处理分组与词频统计任务。文章涵盖具体代码示例、参数设置及去重技巧,帮助开发者选择最适合的场景方案。
Python数据分组基础与字典实现
假设我们面临如下数据结构:
data = [
("apple", 30), ("apple", 35),
("apple", 32), ("pear", 60),
("pear", 32), ("pear", 60),
("banana", 102), ("banana", 104)
]
# 我们希望变成如下格式
"""
[('apple', [30, 35, 32]),
('pear', [60, 32, 60]),
('banana', [102, 104])]
"""面对这种情况,你通常会如何处理?一种直观的解决思路是手动构建一个字典:
data = [
("apple", 30), ("apple", 35),
("apple", 32), ("pear", 60),
("pear", 32), ("pear", 60),
("banana", 102), ("banana", 104)
]
data_dict = {}
for name, count in data:
if name not in data_dict:
data_dict[name] = []
data_dict[name].append(count)
print(data_dict)
"""
{'apple': [30, 35, 32],
'pear': [60, 32, 60],
'banana': [102, 104]}
"""
print(list(data_dict.items()))
"""
[('apple', [30, 35, 32]),
('pear', [60, 32, 60]),
('banana', [102, 104])]
"""这种处理方式完全可行,但我们可以尝试更优雅的写法,即利用字典的 setdefault 方法:
data = [
("apple", 30), ("apple", 35),
("apple", 32), ("pear", 60),
("pear", 32), ("pear", 60),
("banana", 102), ("banana", 104)
]
data_dict = {}
for name, count in data:
# setdefault(k, v) 含义如下
# 当 k 不存在时,将 k: v 设置在字典中,并返回 v
# 当 k 存在时,直接返回 k 对应值
data_dict.setdefault(name, []).append(count)
print(list(data_dict.items()))
"""
[('apple', [30, 35, 32]),
('pear', [60, 32, 60]),
('banana', [102, 104])]
"""setdefault 是一个实用但使用频率相对较低的方法,有时甚至因其使用习惯而不被广泛推崇。主要原因在于每次调用时都需要显式提供一个初始值,例如代码中的空列表 []。此外,初始值的类型可以灵活调整;若希望在添加元素时自动实现去重效果,可将初始值由空列表改为空集合。
使用defaultdict简化分组逻辑
另一种选择是使用位于 collections 模块中的 defaultdict:
from collections import defaultdict
data = [
("apple", 30), ("apple", 35),
("apple", 32), ("pear", 60),
("pear", 32), ("pear", 60),
("banana", 102), ("banana", 104)
]
# 里面接收一个 callable
# 当访问的 k 不存在时,返回 callable 调用之后的值
data_dict1 = defaultdict(list)
for name, count in data:
data_dict1[name].append(count)
print(list(data_dict1.items()))
"""
[('apple', [30, 35, 32]),
('pear', [60, 32, 60]),
('banana', [102, 104])]
"""
# 也可以指定为 set
data_dict2 = defaultdict(set)
for name, count in data:
data_dict2[name].add(count)
print(list(data_dict2.items()))
"""
[('apple', {32, 35, 30}),
('pear', {32, 60}),
('banana', {104, 102})]
"""总体而言,defaultdict 与字典的 setdefault 方法在功能上高度相似,在实际开发中,使用 setdefault 已足以满足大部分需求。
词频统计与Counter类应用
当然,在分组场景中还存在一种特殊情况,即词频统计。如果我们希望统计可迭代对象中各个元素出现的次数,该如何操作呢?
data = ["apple", "apple", "apple",
"pear", "pear", "pear",
"banana", "banana"]
data_dict = {}
for item in data:
# 此处不能使用 setdefault,因为它是函数
# .setdefault(item, 0) += 1 是不符合语法规则的
if item not in data_dict:
data_dict[item] = 0
data_dict[item] += 1
print(data_dict)
"""
{'apple': 3, 'pear': 3, 'banana': 2}
"""
# 或者使用 defaultdict
from collections import defaultdict
data_dict = defaultdict(int)
for item in data:
data_dict[item] += 1
print(data_dict)
"""
defaultdict(<class 'int'>,
{'apple': 3, 'pear': 3, 'banana': 2})
"""针对词频统计这一特定场景,我们还可以借助 collections 模块下的 Counter 类来实现:
from collections import Counter
data = ["apple", "apple", "apple",
"pear", "pear", "pear",
"banana", "banana"]
data_dict = Counter(data)
# 直接搞定,Counter 已经包含了我们之前的逻辑
print(data_dict)
"""
Counter({'apple': 3, 'pear': 3, 'banana': 2})
"""
# Counter 继承 dict,除了支持字典操作之外
# 还提供了很多其它操作,其中一个就是 most_common
# 用于选择出现频率最高的几个元素
print(data_dict.most_common(2))
"""
[('apple', 3), ('pear', 3)]
"""实现过程依然简洁明了。
至此,关于Python优雅进行数据分组及词频统计的详细介绍已告一段落。如需了解更多Python数据分组相关内容,欢迎查阅本站往期文章或继续浏览后续系列内容,感谢大家的支持!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









