如何用简洁的Pandas方法统计DataFrame列中列表的唯一值数量?
问题描述
现有如下Pandas DataFrame:
import pandas as pd import numpy as np data = { 's1': [[1, 2], [None], [2, 3]], 's2': [[4, 5], [6, 7], [3, 2]] } df = pd.DataFrame(data)
初始输出的DataFrame:
s1 s2 0 [1, 2] [4, 5] 1 NaN [6, 7] 2 [2, 3] [3, 2]
需求是统计s1、s2列中列表元素的唯一值数量(忽略None/空值),并整理成如下格式的新DataFrame:
step count 0 1 3 -> 忽略NaN后唯一值为[1,2,3] 1 2 6 -> 唯一值为[1,2,3,4,5,6]
当前的实现方法比较繁琐:
s1_unique = df['s1'].explode().unique() s2_unique = df['s2'].explode().unique() new_df = pd.DataFrame() new_df['step'] = [1,2] new_df['count'] = [len(s1_unique), len(s2_unique)] new_df['name'] = 'Others'
想知道有没有更简洁的DataFrame操作方式实现这个需求。
简洁实现方案
可以利用Pandas的链式操作和内置方法简化代码,直接一步到位:
new_df = ( pd.DataFrame({'step': [1, 2]}) .assign( count=lambda x: [ df['s1'].explode().dropna().nunique(), pd.concat([df['s1'], df['s2']]).explode().dropna().nunique() ], name='Others' ) .assign( count=lambda x: x['count'].astype(str) + [ ' -> 忽略NaN后唯一值为[1,2,3]', ' -> 唯一值为[1,2,3,4,5,6]' ] ) )
关键优化点:
- 用
explode()展开列表元素,dropna()过滤空值,nunique()直接统计唯一值数量,不用手动取unique()再计算长度,更高效直观 - step2需要统计
s1+s2的总唯一值,用pd.concat()合并两列后再处理,逻辑清晰 - 全程用链式操作
assign(),不用先创建空DataFrame再逐个赋值,代码更紧凑
如果不需要保留注释性的描述文本,只需要纯计数的话,代码可以更短:
new_df = pd.DataFrame({ 'step': [1, 2], 'count': [ df['s1'].explode().dropna().nunique(), pd.concat([df['s1'], df['s2']]).explode().dropna().nunique() ], 'name': 'Others' })
内容的提问来源于stack exchange,提问作者Azima
相关产品推荐
相关产品推荐

