
本文介绍一种简洁高效的方法,使用pandas的`replace`与`nunique`组合,快速识别在特定列中(排除0后)包含超过1个不同非零值的数据行。
在数据分析中,常需检测某几列是否“一致”——例如多列编码字段本应相同或为0,若出现多个非零且互异的值,则可能表示异常或特殊逻辑分支。原始实现通过apply(pd.unique)配合复杂lambda判断,不仅可读性差、性能低,还易出错。
更优解是利用pandas内置的统计能力:将0替换为NaN(自然被nunique忽略),再按行计算非空唯一值数量。nunique(axis=1)默认自动跳过NaN,因此只需一步即可完成“排除0后统计不同非零值个数”的核心逻辑。
以下是完整示例代码:
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]
})
# 筛选 col_ 开头的列,将0替换为NaN,按行统计非空唯一值数量 > 1 的行
mask = df.filter(like='col_').replace(0, float('nan')).nunique(axis=1) > 1
result = df[mask].copy()
print(result)输出:
id col_A col_B col_C col_D col_E 0 1 1 2 3 4 5 3 4 0 2 3 4 5
✅ 关键优势:
- 语义清晰:replace(0, NaN) + nunique() 直观表达“忽略零值后统计不同值”;
- 性能优异:避免逐行apply,全程向量化操作;
- 健壮性强:nunique天然处理NaN,无需额外条件判断;
- 灵活可扩展:只需修改filter()条件(如filter(regex=r'^code_'))即可适配任意列名模式。
⚠️ 注意事项:
- 若数据中已存在真实NaN,需先明确其业务含义——本方法会将其与0一并排除在计数外;
- float('nan')可简写为np.nan(需导入import numpy as np),效果一致;
- 如需保留原始列不变,建议对筛选结果使用.copy()避免链式赋值警告。
该方法体现了pandas“用原生操作替代手动循环”的最佳实践,推荐作为类似场景的标准解决方案。










