如何在Pandas中移除DataFrame的镜像重复对行?
Got it,这个镜像重复对的问题我之前也遇到过,其实核心思路就是给每一行生成一个能让镜像对“撞脸”的唯一标识,然后用这个标识去重就行。我给你一步步拆解:
核心思路
你说的镜像重复对,比如[1,2,3,4]和[3,4,1,2],本质是把行的前半段和后半段交换后完全匹配。那我们可以给每一行生成一个镜像无关的标识:把行拆成前后两半,对这两个子序列排序后拼接,这样镜像对的标识就会完全一致,去重时只留其中一行即可。
具体实现(以你的4列DataFrame为例)
假设你的DataFrame是df,先看完整代码,再解释细节:
import pandas as pd # 先创建一个示例DataFrame(和你的场景匹配) data = {'a': [1, 3, 5, 7], 'b': [2, 4, 6, 8], 'c': [3, 1, 7, 9], 'd': [4, 2, 8, 10]} df = pd.DataFrame(data) print("原始数据:") print(df) # 生成镜像标识 half_cols = len(df.columns) // 2 # 列数的一半,这里是2 df['mirror_key'] = df.apply( lambda row: tuple(sorted([tuple(row[:half_cols]), tuple(row[half_cols:])])), axis=1 ) # 去重并移除辅助列 df_cleaned = df.drop_duplicates(subset='mirror_key', keep='first').drop(columns='mirror_key') print("\n移除镜像重复对后的数据:") print(df_cleaned)
代码细节解释
half_cols = len(df.columns) // 2:计算列数的一半,这里4列拆成前2列和后2列。apply(...):对每一行做处理:- 把行的前半段和后半段转成
tuple(因为列表不能作为哈希键); - 对这两个
tuple排序——这样([1,2], [3,4])和([3,4], [1,2])排序后都会变成([1,2], [3,4]); - 把排序后的结果转成
tuple,作为这一行的mirror_key。
- 把行的前半段和后半段转成
drop_duplicates(...):根据mirror_key去重,keep='first'表示保留第一次出现的行,最后删掉辅助列mirror_key。
扩展:适配奇数列的情况
如果以后你的DataFrame是奇数列(比如5列),可以调整拆分逻辑——比如把中间列作为公共部分,前后对称部分排序后加上中间列作为标识。举个例子:
# 假设是5列,拆成前2列、中间1列、后2列 half_cols = (len(df.columns) - 1) // 2 df['mirror_key'] = df.apply( lambda row: tuple(sorted([tuple(row[:half_cols]), tuple(row[half_cols+1:])]) + [row[half_cols]]), axis=1 )
内容的提问来源于stack exchange,提问作者Ixion Chowdhury
相关产品推荐
相关产品推荐

