
本文介绍如何使用 `pandas.dataframe.apply()` 配合自定义逻辑,高效实现**逐行检测重复值**,并以字符串或集合形式返回每行中出现频次大于 1 的所有元素。
在 Pandas 中,默认的 duplicated() 方法作用于列(即纵向),常用于标记或筛选列方向上的重复行;但当需求变为横向识别每行内部的重复值(例如:某一行中 "bar" 出现两次,则提取 "bar"),就需要转向 apply(axis=1) 的行级操作。
核心思路是:对每一行(Series 对象),统计各元素出现次数,筛选出频次 > 1 的值,并去重汇总。以下是推荐的实现方式:
import pandas as pd
df2 = pd.DataFrame({
"A": ["foo", "foo", "foo", "bar"],
"B": [0, 1, 1, 1],
"C": ["A", "foo", "B", "bar"],
"D": ["bar", "bar", "B", "foo"],
"E": ["bar", "bar", "B", "foo"]
})
# ✅ 推荐方案:返回 set(自动去重 + 无序),语义清晰且性能合理
df2["dup"] = df2.apply(
lambda row: {val for val in row if row.tolist().count(val) > 1},
axis=1
)输出结果为:
A B C D E dup
0 foo 0 A bar bar {bar}
1 foo 1 foo bar bar {foo, bar}
2 foo 1 B B B {B}
3 bar 1 bar foo foo {foo, bar}如需与示例中一致的逗号分隔字符串格式(如 "foo, bar"),可进一步转换:
df2["dup"] = df2["dup"].apply(lambda s: ", ".join(sorted(map(str, s))) if s else "")
⚠️ 注意事项:
- row.tolist().count(val) 在大数据集上效率较低(时间复杂度 O(n²)),若处理超万行数据,建议改用 collections.Counter 优化:
from collections import Counter df2["dup"] = df2.apply( lambda row: {val for val, cnt in Counter(row).items() if cnt > 1}, axis=1 ) - 混合数据类型(如 int 和 str)时,Counter 更健壮;而 == 比较在 NaN 存在时需额外处理(NaN != NaN),如含缺失值,建议先用 row.fillna("MISSING") 统一占位。
- 若需保留首次出现顺序,可用 dict.fromkeys(...) 去重后转 list,再过滤。
该方法灵活、可读性强,适用于探索性分析及清洗阶段的行级模式识别任务。










