Counter 实战:计数、排序与缺失值处理
Counter 实战:计数、排序与缺失值处理
collections.Counter 是专门用于统计可哈希对象出现次数的字典子类。它适合处理词频、状态分布、库存变化和日志类别汇总,比手动判断键是否存在更简洁。
1. 从可迭代对象创建计数器
下面统计任务类型出现的次数:
from collections import Counter
records = ["api", "db", "api", "worker", "db", "db"]
counts = Counter(records)
print(dict(counts))
print(counts["db"])
print(counts["cache"])
输出为:
{'api': 2, 'db': 3, 'worker': 1}
3
0
输入列表中的元素会成为键,出现次数成为值。与普通字典不同,读取不存在的键时,Counter 返回 0,不会抛出 KeyError。不过,这次读取不会自动把该键插入计数器,因此 "cache" in counts 仍然是 False。
需要注意,继承自字典的 get() 具有不同语义:
print(counts.get("cache"))
print(counts.get("cache", 0))
输出为:
None
0
因此,希望缺失项稳定得到零时,可以使用下标,或者为 get() 显式提供默认值。
2. 更新已有统计
update() 会累加而不是覆盖计数:
from collections import Counter
counts = Counter(["ok", "error", "ok"])
counts.update(["error", "timeout", "ok"])
counts.update({"error": 2})
print(dict(counts))
输出为:
{'ok': 3, 'error': 4, 'timeout': 1}
传入可迭代对象时,元素每出现一次就加一;传入映射时,则把映射中的值累加到对应键上。这适用于分批读取数据后的持续汇总。
3. 按频次排序
most_common(n) 返回出现次数最高的前 n 项,每项是 (元素, 次数) 元组:
from collections import Counter
counts = Counter(["b", "a", "b", "c", "a", "b"])
print(counts.most_common(2))
print(counts.most_common())
输出为:
[('b', 3), ('a', 2)]
[('b', 3), ('a', 2), ('c', 1)]
省略参数时会返回全部项目。若需要明确规定次数相同情况下的次序,可使用 sorted() 添加第二排序条件:
from collections import Counter
counts = Counter(["pear", "apple", "pear", "banana", "apple"])
ordered = sorted(counts.items(), key=lambda item: (-item[1], item[0]))
print(ordered)
输出为:
[('apple', 2), ('pear', 2), ('banana', 1)]
键函数先按次数降序,再按名称升序。该方式要求第二排序字段之间可以比较;如果键类型混杂,例如同时包含字符串和整数,应改用统一的可比较字段。
4. 减法、零值与负值
subtract() 会执行减法,并保留结果中的零值和负值:
from collections import Counter
stock = Counter({"pen": 5, "book": 2})
stock.subtract({"pen": 3, "book": 2, "bag": 1})
print(dict(stock))
print(dict(+stock))
输出为:
{'pen': 2, 'book': 0, 'bag': -1}
{'pen': 2}
一元加号 +stock 会生成仅保留正计数的新 Counter。如果只想删除某个键,应使用 del stock[key];把值设为零仍会保留该键,并可能影响遍历和序列化结果。
5. 边界条件与适用范围
Counter 的键必须可哈希,字符串、数字和元组通常可以作为键,列表和字典则不可以:
from collections import Counter
try:
Counter([[1, 2], [1, 2]])
except TypeError as exc:
print(type(exc).__name__)
输出为:
TypeError
空输入会得到空计数器。Counter 可以保存零值或负值,因此在将结果解释为“出现次数”前,应确认数据是否经过 subtract() 等操作。它适合内存中规模可控的离散数据统计;若数据量远超可用内存,通常应分批聚合,或采用能够外部存储和查询的方案。
参考资料
- Python 标准库文档 →
collections——容器数据类型 →Counter对象 - Python 标准库文档 → 内置函数 →
sorted
说明:本文由 AI 辅助编写,示例需要读者自行验证。
- 点赞
- 收藏
- 关注作者
评论(0)