“频率”指的是在一个集合(如列表、字符串等)中,每个元素出现的次数,在 Python 中,有多种方法可以实现这个功能,从基础的循环到高效的内置工具和第三方库。

下面我将按照从简单到高级的顺序,介绍几种最常用和最实用的方法。
使用 for 循环和字典(基础方法)
这是最直观、最基础的方法,适合初学者理解频率计算的原理。
原理:
- 创建一个空字典,用来存储元素和它的计数。
- 遍历列表中的每一个元素。
- 如果元素已经存在于字典中,则其对应的计数值加 1。
- 如果元素不存在于字典中,则将其添加到字典中,并设置计数值为 1。
代码示例:

def count_frequencies_manual(data):
"""
使用 for 循环和字典手动计算频率
"""
frequency_dict = {}
for item in data:
if item in frequency_dict:
frequency_dict[item] += 1
else:
frequency_dict[item] = 1
return frequency_dict
# 示例数据
my_list = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple']
# 计算频率
frequencies = count_frequencies_manual(my_list)
# 打印结果
print(frequencies)
# 输出: {'apple': 3, 'banana': 2, 'orange': 1}
更简洁的写法:我们可以使用字典的 .get() 方法来简化 if/else 结构。
def count_frequencies_get(data):
frequency_dict = {}
for item in data:
# .get(item, 0) 会返回 item 对应的值,item 不存在,则返回默认值 0
frequency_dict[item] = frequency_dict.get(item, 0) + 1
return frequency_dict
frequencies = count_frequencies_get(my_list)
print(frequencies)
# 输出: {'apple': 3, 'banana': 2, 'orange': 1}
使用 collections.Counter(推荐方法)
这是 Python 标准库 collections 中的类,专门为计数而设计,它是最高效、最简洁、最推荐的方法。
原理:
Counter 是一个字典的子类,它接收一个可迭代对象(如列表),并自动生成一个元素到其频率的映射。
代码示例:
from collections import Counter
# 示例数据
my_list = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple']
# 直接使用 Counter
frequencies = Counter(my_list)
# 打印结果
print(frequencies)
# 输出: Counter({'apple': 3, 'banana': 2, 'orange': 1})
# Counter 对象和字典一样,可以像字典一样访问
print(frequencies['apple']) # 输出: 3
print(frequencies['orange']) # 输出: 1
# 如果访问不存在的键,不会报错,而是返回 0
print(frequencies['grape']) # 输出: 0
Counter 的常用功能:
-
获取最常见的 N 个元素:
# 获取出现频率最高的 2 个元素 most_common = frequencies.most_common(2) print(most_common) # 输出: [('apple', 3), ('banana', 2)] -
算术运算:
Counter对象支持加减等运算,这在统计多个数据集时非常有用。list1 = ['a', 'b', 'c', 'a', 'b'] list2 = ['a', 'b', 'b', 'd'] counter1 = Counter(list1) counter2 = Counter(list2) # 加法 (合并计数) print(counter1 + counter2) # 输出: Counter({'b': 4, 'a': 2, 'c': 1, 'd': 1}) # 减法 (只保留正数计数) print(counter1 - counter2) # 输出: Counter({'c': 1})
使用 pandas.Series.value_counts()
如果你正在使用 pandas 库进行数据分析,value_counts() 是处理频率问题的最佳选择,它功能强大,且可以轻松地与数据分析流程集成。
原理:
pandas.Series 是一个带标签的一维数组。value_counts() 方法会返回一个按频率降序排列的 Series。
代码示例:
import pandas as pd # 示例数据 my_list = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple'] # 创建一个 Series 对象 series = pd.Series(my_list) # 使用 value_counts() frequencies = series.value_counts() print(frequencies) """ 输出: apple 3 banana 2 orange 1 dtype: int64 """ # value_counts() 默认是降序排列 # 你可以设置 ascending=True 来升序排列 frequencies_asc = series.value_counts(ascending=True) print(frequencies_asc) """ 输出: orange 1 banana 2 apple 3 dtype: int64 """
使用 numpy.unique() (对于数值数据)
如果你主要处理的是数值型数据,并且不关心顺序,numpy.unique() 也是一个不错的选择。
原理:
numpy.unique() 函数可以返回数组中的唯一值,并可以通过 return_counts=True 参数同时返回每个唯一值的计数。
代码示例:
import numpy as np
# 示例数据 (数值型)
my_array = np.array([1, 2, 2, 3, 1, 1, 4, 5, 4])
# 获取唯一值及其计数
unique_values, counts = np.unique(my_array, return_counts=True)
# 将结果组合成一个字典
frequencies = dict(zip(unique_values, counts))
print(frequencies)
# 输出: {1: 3, 2: 2, 3: 1, 4: 2, 5: 1}
总结与选择建议
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
for 循环 + 字典 |
原理简单,无需额外库 | 代码稍长,效率不如 Counter |
学习目的,或在不允许使用标准库的极少数情况下。 |
collections.Counter |
代码最简洁,效率最高,功能丰富(如 most_common) |
需要导入 collections |
强烈推荐,绝大多数情况下计算频率的首选方法。 |
pandas.Series.value_counts() |
与数据分析流程无缝集成,功能强大(如排序、处理缺失值) | 依赖 pandas 库,对于简单任务可能“杀鸡用牛刀” |
数据分析、数据清洗任务中,如果已经使用了 pandas。 |
numpy.unique() |
对数值型数据高效,是 NumPy 生态的一部分 | 主要用于数值数组,不如 Counter 灵活通用 |
科学计算、机器学习领域,当数据已经是 NumPy 数组时。 |
最终建议:
- 日常编程和脚本:直接使用
from collections import Counter,它就是为此而生的。 - 数据分析项目:如果你已经在使用
pandas,value_counts()是最自然的选择。 - 面试或学习:了解
for循环和字典的实现方式,可以展示你对底层原理的理解。
