使用Pandas基于全列值移除重复行,生成唯一组合而非排列
处理Pandas DataFrame中排列重复行的问题
问题说明
给定包含数值排列组合的Pandas DataFrame,需移除所有跨行列存在重复值的行,最终保留的行需满足:每一列的所有值均唯一,且行是原数据中的唯一值组合(而非排列)。
比如示例中,第1行因A列与第0行A列重复被删除,第2行因C列与第0行C列重复被删除,第5行因A列与第4行A列重复、B列与第0行B列重复被删除。
示例数据
初始代码
import itertools import pandas as pd check = list(itertools.permutations([1, 2, 3])) test = pd.DataFrame(check, columns=['A', 'B', 'C'])
初始DataFrame
| index | A | B | C |
|---|---|---|---|
| 0 | 1 | 2 | 3 |
| 1 | 1 | 3 | 2 |
| 2 | 2 | 1 | 3 |
| 3 | 2 | 3 | 1 |
| 4 | 3 | 1 | 2 |
| 5 | 3 | 2 | 1 |
期望输出
| index | A | B | C |
|---|---|---|---|
| 0 | 1 | 2 | 3 |
| 3 | 2 | 3 | 1 |
| 4 | 3 | 1 | 2 |
解决方案
方法1:逐步筛选法(高效)
通过逐步筛选符合条件的行,确保每一行的各列值都不与已选中行的对应列值重复:
import pandas as pd import itertools # 生成初始数据 check = list(itertools.permutations([1, 2, 3])) test = pd.DataFrame(check, columns=['A', 'B', 'C']) selected = [] remaining = test.copy() col_count = test.shape[1] while len(selected) < col_count: if not selected: # 先选中第一行 selected.append(remaining.iloc[0]) remaining = remaining.iloc[1:] else: # 遍历剩余行,找到符合条件的行 for idx, row in remaining.iterrows(): valid = True # 检查当前行每一列的值是否在已选中行的对应列中存在 for col in test.columns: if row[col] in [s[col] for s in selected]: valid = False break if valid: selected.append(row) remaining = remaining.drop(idx) break # 将选中的行转为DataFrame result = pd.DataFrame(selected).reset_index(drop=False) print(result)
方法2:组合遍历法(直观)
遍历所有行数等于列数的行组合,找到第一个满足每列值均唯一的组合:
import pandas as pd import itertools # 生成初始数据 check = list(itertools.permutations([1, 2, 3])) test = pd.DataFrame(check, columns=['A', 'B', 'C']) col_count = test.shape[1] result = None # 遍历所有可能的col_count行组合 for candidate_idx in itertools.combinations(test.index, col_count): subset = test.loc[candidate_idx] # 检查每一列的唯一值数量是否等于列数(即无重复) if all(subset[col].nunique() == col_count for col in subset.columns): result = subset break print(result)
结果验证
两种方法运行后均会输出符合期望的DataFrame,每一列的所有值均唯一,且行是原数据中的有效组合。
内容的提问来源于stack exchange,提问作者psychcoder
相关产品推荐
相关产品推荐

