如何优雅筛选DataFrame中指定列非零不同值超1个的行?
问题:筛选编码列中非零不同值数量>1的行
我的DataFrame包含5个存储编码值的列,这些列的编码值通常要么全部相同,要么包含0。我需要筛选出这些列中非零不同值数量超过1个的行,例如示例中id为1和4的行。
示例数据
import pandas as pd df = pd.DataFrame({'id':[1,2,3,4],'col_A':[1,1,1,0],'col_B':[2,1,0,2],'col_C':[3,1,0,3],'col_D':[4,1,1,4],'col_E':[5,1,1,5]})
对应的表格:
| id | col_A | col_B | col_C | col_D | col_E |
|---|---|---|---|---|---|
| 1 | 1 | 2 | 3 | 4 | 5 |
| 2 | 1 | 1 | 1 | 1 | 1 |
| 3 | 1 | 0 | 0 | 1 | 1 |
| 4 | 0 | 2 | 3 | 4 | 5 |
现有实现(写法繁琐)
df['cats'] = df.loc[:,df.filter(like='col_').columns].apply(pd.unique, axis=1) df[df['cats'].apply(lambda x:(len(x)-1) if 0 in x else len(x))>1]
优化方案
方法一:替换0为NaN后统计不同值数量
利用nunique的向量化操作,直接按行统计排除0后的不同值数量,无需创建临时列:
col_cols = df.filter(like='col_').columns result = df[df[col_cols].replace(0, pd.NA).nunique(axis=1) > 1]
方法二:用mask过滤0后统计
通过mask将0值标记为缺失值,再统计不同值数量:
col_cols = df.filter(like='col_').columns result = df[df[col_cols].mask(df[col_cols]==0).nunique(axis=1) > 1]
这两种方法都避免了循环式的apply(pd.unique),效率更高,代码也更简洁直观。
内容的提问来源于stack exchange,提问作者Ramsay
相关产品推荐
相关产品推荐

