value_counts()是统计单列频次与占比最常用方法,默认降序排列,加normalize=True得占比,dropna=False保留NaN;多列组合用groupby().size()或crosstab();转DataFrame用reset_index(name='count');大数据量建议sort=False和astype('category')提速。

用 value_counts() 快速统计单列频次和占比
直接调用 value_counts() 是最常用也最稳妥的方式。它默认按频次降序排列,加参数 normalize=True 就能返回占比(小数形式),加 dropna=False 可保留缺失值统计。
常见错误是忽略 dropna 参数——当列含 NaN 时,默认会丢掉,导致总数变少、占比失真。如果业务上需要把空值当作一类处理,必须显式传入 dropna=False。
-
df['category_col'].value_counts()→ 返回频次 Series -
df['category_col'].value_counts(normalize=True)→ 返回占比(总和为 1.0) -
df['category_col'].value_counts(dropna=False, normalize=True)→ 含NaN的完整占比
对多列同时统计:用 groupby().size() 或 crosstab()
单列统计够用,但若需看两个类别变量的组合分布(比如“城市 × 性别”),value_counts() 支持多列传入,但更清晰的做法是用 groupby().size() 或 pd.crosstab()。
groupby().size() 返回的是 MultiIndex Series,适合后续做归一化;crosstab() 直接生成二维表,更适合展示或导出。注意 crosstab() 默认忽略 NaN,如需包含,得先用 fillna() 替换或传入 dropna=False(Pandas ≥ 1.5.0)。
立即学习“Python免费学习笔记(深入)”;
图片提示词生成器?不止如此。 马甲系统 —— 把脑海中的画面,翻译成AI能理解的专业表达。 用得越多,它越懂你:首次需要多问几句确认方向,用久了几乎一说就懂。 用得越多,它越快:缓存机制让后续对话越来越省。 RAG进化:成功案例持续入库,越跑越聪明。 输入「新手指南」查看完整功能介绍
-
df.groupby(['col_a', 'col_b']).size()→ 组合频次 -
pd.crosstab(df['col_a'], df['col_b'])→ 行列交叉表 - 想转成占比?在
crosstab()后链式调用.apply(lambda x: x / x.sum(), axis=1)(行占比)或axis=0(列占比)
结果转成 DataFrame 并添加百分比列
原始 value_counts() 返回的是 Series,常需转成带列名的 DataFrame 方便后续拼接或导出。直接用 reset_index(name='count') 即可;占比列建议手动计算,避免浮点精度误差累积。
容易踩的坑是直接对 normalize=True 的结果乘 100 得到百分比——虽然数值上没问题,但类型是 float,显示不友好。更推荐用 round(2) 控制小数位,并显式转成字符串加 % 符号用于展示(但注意:加符号后就不再是数值,不能参与计算)。
freq_df = df['cat'].value_counts().reset_index(name='count')freq_df['pct'] = (freq_df['count'] / freq_df['count'].sum() * 100).round(2)- 如需显示列:
freq_df['pct_display'] = freq_df['pct'].astype(str) + '%'
性能与内存:大数据量下慎用 value_counts(sort=False)
当类别数极多(比如百万级唯一值)且不关心排序时,加 sort=False 能显著提速——Pandas 默认排序开销不小。另外,value_counts() 内部会构建哈希表,对超大 DataFrame(千万行以上)可能触发内存压力,此时可考虑分块读取或用 category 类型提前编码。
一个被忽略的细节:value_counts() 对 object 类型列比对 category 类型慢数倍。如果该列实际类别有限,先执行 df['col'] = df['col'].astype('category') 再统计,既省内存又快。
- 提速关键:
df['col'].value_counts(sort=False) - 内存优化前提:确认该列真实类别数远小于行数,再转
category - 别盲目转:
category对高频更新/追加数据不友好,仅适用于静态或低频变更场景

















