value_counts()仅适用于Series,多列组合频次需先groupby再调用;normalize=True按每组内部归一化,非全局;dropna=False需在groupby中设置才保留含NaN分组。

value_counts() 默认只算单列,多组频率得用 groupby + value_counts
直接对 DataFrame 调用 value_counts() 会报错或返回意外结果——它只接受 Series。想按「多列组合」统计频次(比如按 region 和 category 一起分组计数),必须先 groupby,再链式调用 value_counts()。
-
df.groupby(['region', 'category']).size()是等效写法,但不排序,也不自动归一化 -
df.groupby(['region', 'category'])['status'].value_counts()可指定目标列,适合带筛选的场景 - 默认返回的是 MultiIndex Series,索引是分组键+原列值;加
sort=False可禁用自动降序排列 - 若需转成普通 DataFrame,跟
reset_index(name='count')就行,name参数指定新列名,别漏掉
normalize=True 会按「每组内部」归一化,不是全局比例
很多人以为 normalize=True 是把所有频次除以总行数,实际它是按每个分组单独算比例。比如 A 组有 10 行、其中 'X' 出现 4 次,那 A 组里 'X' 的归一化值就是 0.4;B 组有 20 行、'X' 出现 2 次,对应就是 0.1 —— 两者不可直接跨组比较“占比高低”。
- 要全局归一化:先算总频次
df['col'].value_counts(),再手动除以len(df) - 如果用了
groupby().value_counts(normalize=True),结果类型是float64,不是整数,注意后续计算类型匹配 - 配合
dropna=False才能包含 NaN 的统计,否则 NaN 被静默丢弃
dropna=False 不起作用?检查是否在 groupby 前就丢了 NaN
value_counts(dropna=False) 确实能统计 NaN,但它只管目标列本身。如果分组列(比如 groupby(['a', 'b']))里有 NaN,pandas 默认会直接跳过整行——根本进不到 value_counts 这一步。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- 验证方法:运行
df[['a', 'b']].isna().any(axis=1).sum(),看分组列是否有空值 - 保留含 NaN 的分组:用
groupby(..., dropna=False)(pandas ≥ 1.1.0),不是value_counts的参数 - 旧版 pandas(dropna 参数,得先
fillna()占位,比如填字符串',但要注意别和真实数据冲突'
性能差?避免在大表上反复调 groupby + value_counts
对千万级 DataFrame 频繁做 groupby().value_counts() 很慢,因为每次都会重建分组哈希表。如果只是想查几个固定组合的频次,用布尔索引 + value_counts() 更快。
- 例如查
region=='North'且category=='A'的status分布:df.query("region == 'North' and category == 'A'")['status'].value_counts() -
groupby().value_counts(sort=False)比默认排序快一点,尤其结果量大时 - 内存敏感场景下,加
ascending=True不会提速,反而可能因排序增加开销
实际用的时候,最常卡住的不是语法,而是搞不清 dropna 到底在哪一层生效、以及 normalize 的作用域范围——这两处不画个草图对照数据,很容易对着结果发懵。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










