Pandas pd.value_counts() 函数
pd.value_counts() 是 Pandas 库中用于统计各值出现频次的函数。它会计算数组中每个唯一值出现的次数,并按频次降序排列返回。
这是分类数据分析中最常用的函数之一,可以快速了解数据的分布情况,例如统计投票结果、产品类别分布等。
单词释义: value_counts 意为"统计值",即统计每个值出现的次数。
基本语法与参数
pd.value_counts() 是 Pandas 库的顶级函数,用于计算每个唯一值的频次。
语法格式
pd.value_counts(values, sort=True, ascending=False, normalize=False, bins=None, dropna=True)
参数说明
- 参数:
values- 类型: Series、类数组对象。
- 描述: 要统计频次的数据。通常是一个 Series。
- 参数:
sort- 类型> 布尔值。
- 是否按频次排序。默认为
True(按频次降序)。
- 参数:
ascending- 类型: 布尔值。
- 如果为
True,按频次升序排列;如果为False(默认),按频次降序排列。
- 参数:
normalize- 类型: 布尔值。
- 如果为
True,返回每个值出现的比例(0 到 1 之间),而不是绝对频次。默认为False。
- 参数:
bins- 类型: 整数或 None。
- 如果指定整数,将数值数据分箱后统计频次(类似直方图)。不适用于分类数据。
- 参数:
dropna- 类型: 布尔值。
- 是否包含 NaN 在统计结果中。默认为
True(不包含)。
函数说明
- 返回值: 返回一个 Series,索引是唯一值,值是频次(或比例)。
- 效果: 统计并展示每个唯一值出现的次数。
实例
让我们通过一系列从简单到复杂的例子,彻底掌握 pd.value_counts() 的用法。
示例 1:基础用法 - 统计分类数据的频次
实例
import pandas as pd
import numpy as np
# 1. 创建包含重复值的 Series
colors = pd.Series(['red', 'blue', 'green', 'red', 'blue', 'yellow', 'red', 'blue', 'blue'])
print("=== 原始 Series ===")
print(colors)
# 2. 使用 pd.value_counts() 统计频次
result = pd.value_counts(colors)
print("\n=== pd.value_counts() 频次统计 ===")
print(result)
import numpy as np
# 1. 创建包含重复值的 Series
colors = pd.Series(['red', 'blue', 'green', 'red', 'blue', 'yellow', 'red', 'blue', 'blue'])
print("=== 原始 Series ===")
print(colors)
# 2. 使用 pd.value_counts() 统计频次
result = pd.value_counts(colors)
print("\n=== pd.value_counts() 频次统计 ===")
print(result)
运行结果预期:
=== 原始 Series === 0 red 1 blue 2 green 3 red 4 blue 5 yellow 6 red 7 blue 8 blue dtype: object === pd.value_counts() 频次统计 === blue 4 red 3 green 1 yellow 1 dtype: int64
代码解析:
- 结果按频次降序排列,blue 出现最多(4 次),red 次之(3 次),green 和 yellow 各 1 次。
- 返回的是一个 Series,索引是颜色值,值是出现的次数。
示例 2:使用 normalize 参数计算比例
normalize=True 可以将频次转换为比例,便于查看数据的相对分布。
实例
import pandas as pd
import numpy as np
# 创建投票数据
votes = pd.Series(['A', 'B', 'A', 'C', 'A', 'B', 'A', 'A', 'C', 'B', 'A', 'B'])
print("=== 投票数据 ===")
print(votes)
# 1. 绝对频次
print("\n=== 绝对频次 ===")
print(pd.value_counts(votes))
# 2. 相对比例(normalize=True)
print("\n=== 相对比例 ===")
result_normalized = pd.value_counts(votes, normalize=True)
print(result_normalized)
print(f"\n比例总和: {result_normalized.sum():.2f}")
# 3. 按升序排列
print("\n=== 升序排列 ===")
print(pd.value_counts(votes, ascending=True))
import numpy as np
# 创建投票数据
votes = pd.Series(['A', 'B', 'A', 'C', 'A', 'B', 'A', 'A', 'C', 'B', 'A', 'B'])
print("=== 投票数据 ===")
print(votes)
# 1. 绝对频次
print("\n=== 绝对频次 ===")
print(pd.value_counts(votes))
# 2. 相对比例(normalize=True)
print("\n=== 相对比例 ===")
result_normalized = pd.value_counts(votes, normalize=True)
print(result_normalized)
print(f"\n比例总和: {result_normalized.sum():.2f}")
# 3. 按升序排列
print("\n=== 升序排列 ===")
print(pd.value_counts(votes, ascending=True))
运行结果预期:
=== 投票数据 === 0 A 1 B 2 A 3 C 4 A 5 B 值 'A' 出现 6 次,占 50% 值 'B' 出现 4 次,约 33.3% 值 'C' 出现 2 次,约 16.7% === 相对比例 === A 0.500000 B 0.333333 C 0.166667 dtype: float64 === 升序排列 === C 2 B 4 A 6 dtype: int64
代码解析:
- 使用
normalize=True可以快速计算各类别的占比。 - 所有比例相加等于 1.0,便于进行占比分析。
- 使用
ascending=True可以按频次升序查看结果。
示例 3:处理数值数据和使用 bins 参数
对于连续数值,可以使用 bins 参数进行分箱统计。
实例
import pandas as pd
import numpy as np
# 1. 创建数值数据
scores = pd.Series([85, 90, 78, 92, 88, 76, 95, 82, 70, 89, 91, 77, 84, 86])
print("=== 学生成绩 ===")
print(scores)
# 2. 不分箱 - 统计每个唯一值
print("\n=== 统计每个分数 ===")
print(pd.value_counts(scores))
# 3. 使用 bins 参数分箱
print("\n=== 分成 4 个箱 ===")
result_bins = pd.value_counts(scores, bins=4)
print(result_bins)
# 4. 查看分箱的边界
print("\n=== 分箱边界 ===")
print(f"最小值: {scores.min()}, 最大值: {scores.max()}")
import numpy as np
# 1. 创建数值数据
scores = pd.Series([85, 90, 78, 92, 88, 76, 95, 82, 70, 89, 91, 77, 84, 86])
print("=== 学生成绩 ===")
print(scores)
# 2. 不分箱 - 统计每个唯一值
print("\n=== 统计每个分数 ===")
print(pd.value_counts(scores))
# 3. 使用 bins 参数分箱
print("\n=== 分成 4 个箱 ===")
result_bins = pd.value_counts(scores, bins=4)
print(result_bins)
# 4. 查看分箱的边界
print("\n=== 分箱边界 ===")
print(f"最小值: {scores.min()}, 最大值: {scores.max()}")
运行结果预期:
=== 学生成绩 === [85, 90, 78, 92, 88, 76, 95, 82, 70, 89, 91, 77, 84, 86] === 统计每个分数 === 85 2 90 1 78 1 92 1 88 1 76 1 95 1 82 1 70 1 89 1 91 1 77 1 84 1 86 1 Name: count, dtype: int64 === 分成 4 个箱 === result_bins = pd.value_counts(scores, bins=4) (88.75, 95.0] 5 (82.5, 88.75] 4 (76.25, 82.5] 3 (69.97399999999999, 76.25] 2 Name: count, dtype: int64 === 分箱边界 === 最小值: 70, 最大值: 95
这类似于直方图,能够看到成绩分布主要集中在中高分区间。bins 参数将数值数据按照范围划分为离散的箱子,然后统计每个箱子中的数据量。
示例 4:处理缺失值
使用 dropna 参数可以控制是否统计缺失值。
实例
import pandas as pd
import numpy as np
# 1. 包含缺失值的数据
data = pd.Series(['a', 'b', np.nan, 'a', None, 'c', np.nan, 'b', 'a'])
print("=== 包含缺失值的数据 ===")
print(data)
# 2. 默认不包含 NaN(dropna=True)
print("\n=== 默认不包含 NaN ===")
print(pd.value_counts(data))
# 3. 包含 NaN(dropna=False)
print("\n=== 包含 NaN ===")
print(pd.value_counts(data, dropna=False))
# 4. 统计数值型缺失值
numeric_data = pd.Series([1, 2, np.nan, 3, 2, np.nan, 1, 4])
print("\n=== 数值型数据包含 NaN ===")
print(pd.value_counts(numeric_data, dropna=False))
import numpy as np
# 1. 包含缺失值的数据
data = pd.Series(['a', 'b', np.nan, 'a', None, 'c', np.nan, 'b', 'a'])
print("=== 包含缺失值的数据 ===")
print(data)
# 2. 默认不包含 NaN(dropna=True)
print("\n=== 默认不包含 NaN ===")
print(pd.value_counts(data))
# 3. 包含 NaN(dropna=False)
print("\n=== 包含 NaN ===")
print(pd.value_counts(data, dropna=False))
# 4. 统计数值型缺失值
numeric_data = pd.Series([1, 2, np.nan, 3, 2, np.nan, 1, 4])
print("\n=== 数值型数据包含 NaN ===")
print(pd.value_counts(numeric_data, dropna=False))
运行结果预期:
=== 包含缺失值的数据 === 0 a 1 b 2 NaN 3 a 4 None 5 c 6 NaN 7 b 8 a dtype: object === 默认不包含 NaN === a 3 b 2 c 1 dtype: 64 === 包含 NaN (dropna=False) === a 3 b 2 NaN 2 # 2 个 NaN (2 个 np.nan) c 1 dtype: int64 === 数值型数据包含 NaN === 1.0 2 2.0 2 NaN 2 # 2 个 NaN 3.0 1 4.0 1 dtype: int64
代码解析:
- 默认情况下(
dropna=True),不统计 NaN 值。 - 使用
dropna=False可以查看缺失值的数量,这在数据质量分析中很有用。 - 数值型数据同样适用。
提示:
pd.value_counts()是探索性数据分析中最重要的函数之一,可以快速了解数据的分布情况。如果只需要获取唯一值列表而不需要频次,请使用pd.unique()函数。

Pandas 常用函数