如何用Pandas实现R语言中的双向重复序列去重?
用Pandas实现双向重复序列对的去重
我之前用R搞定了双向重复序列对的去重——就是处理像seq1 seq2和seq2 seq1这种互为颠倒的序列对,最终得到唯一的序列集合,对应的R代码如下:
data <- read.table("dataframe.txt") for (i in 1:nrow(data)) { data[i,c(2,3)] = sort(data[i,c(2,3)]) } data2 = data[!duplicated(data[,c(2,3)]),] write.csv(data2,"data_without_duplicated")
现在想换成Pandas实现同样的逻辑,先给你看看我的实际数据样例:
cluster_name qseqid sseqid pident_x pident_y length qstart qend sstart send qspec sspec 13 cluster_016663 EOG090X00GO_0035_0035_1 EOG090X00GO_0042_0035_1 0.93 93.0 1179 1 1175 1 1179 0035 0042 14 cluster_016663 EOG090X00GO_0035_0035_1 EOG090X00GO_0042_0042_1 0.93 93.0 1179 1 1175 1 1179 0035 0042 16 cluster_016663 EOG090X00GO_0035_0042_1 EOG090X00GO_0042_0035_1 0.93 93.0 1179 1 1175 1 1179 0035 0042 17 cluster_016663 EOG090X00GO_0035_0042_1 EOG090X00GO_0042_0042_1 0.93 93.0 1179 1 1175 1 1179 0035 0042 19 cluster_016663 EOG090X00GO_0042_0035_1 EOG090X00GO_0035_0035_1 0.93 93.0 1179 1 1179 1 1175 0042 0035 20 cluster_016663 EOG090X00GO_0042_0035_1 EOG090X00GO_0035_0042_1 0.93 93.0 1179 1 1179 1 1175 0042 0035 22 cluster_016663 EOG090X00GO_0042_0042_1 EOG090X00GO_0035_0035_1 0.93 93.0 1179 1 1179 1 1175 0042 0035 23 cluster_016663 EOG090X00GO_0042_0042_1 EOG090X00GO_0035_0042_1 0.93 93.0 1179 1 1179 1 1175 0042 0035
我自己试了一段Pandas脚本,但逻辑好像有点混乱,你帮我调整下:
data_wo_eqSpec.to_csv("dataframe.txt", sep='\t') print("prem1:",data_wo_eqSpec.shape) data_wo_eqSpec=data_wo_eqSpec.astype(str) data_wo_eqSpec.iloc[:,1:3]=np.sort(data_wo_eqSpec.iloc[:,1:3].values,1) data_wo_eqSpec2= data_wo_eqSpec.drop_duplicates(list(data_wo_eqSpec.iloc[:,1:3])) print("prem:",data_wo_eqSpec2.shape) data_wo_eqSpec=pd.read_csv("data_without_duplicated") print("deus:",data_wo_eqSpec.shape)
正确的Pandas实现方案
其实核心逻辑和R是一致的:先对每行的目标列排序,再根据排序后的列去重。这里给你整理了更清晰的代码:
import pandas as pd import numpy as np # 1. 读取原始数据(假设你的数据文件是制表符分隔的txt) data = pd.read_csv("dataframe.txt", sep="\t") # 2. 对每行的qseqid和sseqid列进行排序,这样互为颠倒的序列对会变成完全相同的组合 # 用列名指定更清晰,避免用iloc索引出错(万一列顺序变了就麻烦) data[["qseqid", "sseqid"]] = np.sort(data[["qseqid", "sseqid"]].values, axis=1) # 3. 根据排序后的qseqid和sseqid列去重,保留第一次出现的行 # subset参数指定用来判断重复的列,keep="first"保留第一个出现的条目 data_no_duplicates = data.drop_duplicates(subset=["qseqid", "sseqid"], keep="first") # 4. 保存去重后的结果,index=False避免保存额外的索引列 data_no_duplicates.to_csv("data_without_duplicated.csv", sep="\t", index=False) # 查看行数变化,验证去重效果 print(f"去重前总共有 {data.shape[0]} 行") print(f"去重后总共有 {data_no_duplicates.shape[0]} 行")
对你原有代码的小修正说明
- 原有代码里先保存文件又重新读取,逻辑有点绕,直接在内存中处理更高效
drop_duplicates需要用subset参数指定去重依据的列,而不是直接传入列的列表- 除非你的序列ID有混合类型(比如数字和字符串),否则不需要强制
astype(str),保持原类型即可
内容的提问来源于stack exchange,提问作者Grendel
相关产品推荐
相关产品推荐

