Python如何统计分组内不重复的元素个数_聚合时指定nunique统计函数
Python分组去重计数:掌握nunique()函数,提升数据分析效率
在数据分析工作中,按组统计唯一值数量是一项常见且关键的任务。例如,分析每个产品类别下的独立访客数,或计算每个销售区域每年上架的不同商品种类。此时,pandas库中的nunique()函数便成为高效解决此类问题的首选工具。
免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈
nunique()是pandas中专门用于分组后计算唯一值数量的聚合方法。默认情况下自动忽略NaN空值,可通过dropna=False参数将NaN视为一个独立类别。使用时需明确指定目标列,且不适用于列表、字典等不可哈希的数据类型。

使用groupby结合nunique()快速实现分组去重统计
在pandas.DataFrame.groupby进行分组聚合操作时,直接调用nunique()方法是为“唯一值计数”场景量身定制的解决方案。相比先使用unique()获取唯一值列表再用len()计算长度的传统方法,它更加简洁且性能更优,尤其在处理缺失值NaN时拥有清晰的默认逻辑——自动排除。
首先需要明确一个常见误区:切勿将nunique()与count()或size()混淆。后两者分别统计非空值数量和总行数,均不具备去重功能。
- NaN缺失值处理:
nunique()默认忽略所有NaN值。若业务分析中需要将“空值”作为一个独立的分类进行统计,只需设置参数dropna=False即可。 - 支持的列数据类型:该函数对数值型列和字符串列均可直接使用。但需注意,如果目标列包含列表、字典等可变嵌套结构,直接调用会引发
TypeError: unhashable type错误。 - 执行效率对比:相较于使用
apply(lambda x: x.nunique())这种通用但效率较低的方式,直接调用内置的nunique()方法在处理大规模数据集时能显著提升计算速度。
单列分组与单目标列统计:基础应用模式
这是最典型的使用场景。例如,按照category(产品类别)进行分组,并统计每个类别下有多少个不同的user_id(用户ID):
df.groupby('category')['user_id'].nunique()
上述代码将返回一个pandas.Series对象,其索引为各个分组类别,对应的值为该组内用户ID的去重计数。若希望将结果转换为标准的DataFrame格式,可在其后链式调用.reset_index(name='nunique_user')进行重置。
立即学习“Python免费学习笔记(深入)”;
- 关于NaN的补充说明:若目标列中存在大量
NaN,且业务逻辑要求将“空用户ID”视为一种有效状态,务必使用.nunique(dropna=False)。 - 关键操作细节:必须准确指定目标列。错误地写成
df.groupby('category').nunique()会导致对所有数值列进行去重计数,而非仅针对某一列。务必使用['col']或[['col']]的语法来明确指定需要统计的列。
多列分组与多目标列分别统计:进阶聚合分析
面对更复杂的分析需求,例如需要同时按照“地区”和“年份”进行双重分组,并分别计算“产品ID”、“卖家ID”和“国家”的唯一值数量时,可以通过字典形式将聚合规则传递给agg()函数,使代码逻辑清晰明了:
df.groupby(['region', 'year']).agg({
'product_id': 'nunique',
'seller_id': 'nunique',
'country': 'nunique'
})
执行后将得到一个具有多层索引(MultiIndex)的DataFrame,其列名为之前指定的各个字段,数值则为对应的nunique统计结果。
- 代码书写规范:聚合字典中的字段名和聚合函数名均需使用引号包裹(例如
'nunique')。若遗漏引号直接书写nunique,将引发NameError错误。 - 混合聚合操作:若需对同一列同时计算唯一值数量和最大值,可写作
'product_id': ['nunique', 'max']。但需注意,这样生成的列名会变为多级索引。 - 代码风格建议:尽量避免在同一个
agg字典中混合使用字符串函数名和lambda表达式。虽然{'a': 'nunique', 'b': lambda x: x.nunique()}的写法可以执行,但在代码可读性和执行性能上,统一使用字符串函数名是更佳的选择。
解决“unhashable type”不可哈希类型错误
这是使用nunique()时可能遇到的一个典型障碍。当目标列的数据类型为列表(list)、字典(dict)或集合(set)等不可哈希(unhashable)的类型时,直接调用会抛出TypeError: unhashable type: 'list'异常。其根本原因在于nunique()的底层实现依赖于set()进行去重,而列表等可变类型无法直接作为集合的元素。
解决方案并非修改函数本身,而是在调用前将数据转换为可哈希的表示形式:
- 列表列的处理:若列表内的元素本身可哈希(如字符串、数字),可将其转换为元组(
tuple)。例如:df['tags_tuple'] = df['tags'].apply(lambda x: tuple(x) if isinstance(x, list) else None),然后对生成的tags_tuple列使用nunique()。 - 字典列的处理:可考虑进行序列化。例如使用
frozenset(dict.items()),或更稳健地使用json.dumps(sorted(dict.items()))将其转换为JSON字符串(对字典项排序是为了确保顺序一致,避免因键的顺序不同导致相同的字典被误判为不同值)。 - 通用替代方案:如果数据转换较为复杂,一个更直接但效率稍低的方法是:先基于分组键和目标列进行去重(使用
drop_duplicates),然后再进行分组计数。例如:df.drop_duplicates(['group_col', 'target_col']).groupby('group_col').size()。
总结来说,nunique()函数虽看似简单,但目标列的数据类型、NaN值的处理方式以及对嵌套数据结构的应对策略是三个最易出错的环节。在实际应用中,养成良好的数据探查习惯,先通过df['col'].dtype查看数据类型,并用df['col'].head()预览数据样本,往往能事半功倍,有效避免踩坑。
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
同类文章
怎么利用 System.err 输出错误流并在控制台中以醒目的颜色标记(取决于终端)
怎么利用 System err 输出错误流并在控制台中以醒目的颜色标记(取决于终端) System err 默认行为不带颜色,终端是否显示颜色取决于自身支持 首先得明确一点:System err 本质上只是 Ja va 标准库里的一个 PrintStream 对象。它本身并不负责“颜色”这种花哨的玩
如何在 Java 中使用 ThreadLocal.remove() 确保在线程池复用场景下不会发生数据污染
如何在 Ja va 中使用 ThreadLocal remove() 确保在线程池复用场景下不会发生数据污染 说到线程池和 ThreadLocal 的搭配使用,一个看似不起眼、实则极易“踩坑”的细节就是数据清理。想象一下,你精心设计的线程池正在高效运转,却因为某个任务留下的“数据尾巴”,导致后续任务
怎么利用 Arrays.asList() 转换出的“受限列表”理解其对 add() 等修改操作的限制
Arrays asList():一个“受限”但实用的列表视图 在Ja va开发中,Arrays asList()是一个高频使用的方法,但你是否真正了解它返回的是什么?一个常见的误解是,它直接生成了一个标准的ArrayList。事实并非如此。 简单来说,Arrays asList()返回的并非我们熟悉
如何在 Java 中利用 try-catch 实现对“软错误”的平滑感知与非侵入式监控日志记录
如何在 Ja va 中利用 try-catch 实现对“软错误”的平滑感知与非侵入式监控日志记录 在 Ja va 开发中,我们常常会遇到一些“软错误”——它们不会让程序直接崩溃,却可能悄悄影响业务的正确性或用户体验。比如,调用第三方 API 时返回了空响应、缓存查询未命中、配置文件里某个非关键项缺失
Django怎么防止Celery任务重复执行_Python结合Redis实现分布式锁
Django怎么防止Celery任务重复执行:Python结合Redis实现分布式锁 你遇到过吗?明明只发了一次任务,后台却执行了两次。这不是代码写错了,而是分布式环境下一个经典的老朋友:多个worker同时抢到了同一个活儿。 为什么Celery任务会重复执行 问题的根源在于竞争。想象一下,多个Ce
- 日榜
- 周榜
- 月榜
1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10
相关攻略
2015-03-10 11:25
2015-03-10 11:05
2021-08-04 13:30
2015-03-10 11:22
2015-03-10 12:39
2022-05-16 18:57
2025-05-23 13:43
2025-05-23 14:01
热门教程
- 游戏攻略
- 安卓教程
- 苹果教程
- 电脑教程
热门话题

