TL:DR
我需要过滤整个数据帧(700k +行),如果我发现重复的数据或rs
列中的多个值,则需要将其余列与其他相同的行进行比较,并将if all cols == True
放入{ {1}}或DF1
,将所有带有此if rest cols = False
的行放入rs
。如果rs在wholeDf中只有一次,则应将其移至DF2
。我写了一个函数,但是要花很长时间。
_
我有一些CSV文件,看起来:
DF1
我需要获得所有记录,且不能重复。
所以我first:
SNP_name chrom pos rs
A1 2 2121 4234
A2 2 4234 3244
A52 1 5531 2223
A1 3 6666 5324
...
second:
SNP_name chrom pos rs
A1 2 2121 4234
A2 2 4234 3244
A11 5 5555 3213
A11 5 5555 3213
....
third:
SNP_name chrom pos rs
A44 4 3242 e2311
A2 2 4234 3244
A2 2 4234 3244
A55 4 5233 3122
...
将所有DF都合为一个:
concat
(我知道应该在这里使用,但是首先要起作用,然后再进行优化:)
我得到一个wholeDF = pd.concat([df_list[0],df_list[1],df_list[2],df_list[3],df_list[4],df_list[5],df_list[6]])
:
WholeDF
现在我提取出rs值:
SNP_name chrom pos rs
A1 2 2121 4234
A2 2 4234 3244
A52 1 5531 2223
A1 3 6666 5324
...
A1 2 2121 4234
A2 2 4234 3244
A11 5 5555 3213
A11 5 5555 3213
....
A44 4 3242 e2311
A2 2 4234 3244
A2 2 4234 3244
A55 4 5233 3122
...
我得到了所有rs列表以及出现的次数。 例如:
values = wholeDF.rs.value_counts()
等
我要做什么:
而且我只想为每个4234 2
3244 4
2223 1
保留一条记录,但前提是它们的色标和SNP_name相同。
因此在上面的示例中,它应检查rs
在其余行中是否具有相同的另一个值。如果是,请先休息。如果否,则应将所有带有此rs的行都放入logDF。
根据上述示例得出的结果:
我试图通过for循环来做到这一点(它更像是伪代码,我是从内存中写的):
4234
因此,在这种情况下,我得到了正确的列表。以后我可以删除重复项。
但是当我运行它时-WholeDF有72.5万行-处理需要几个小时。
有可能以最简单的方式做到这一点,例如在没有for循环的pandas中? 还是另一个更好的主意?
有人可以帮助我完成这项任务吗?
答案 0 :(得分:1)
如果您真的想保留掉的行,也许这行得通:
import numpy as np
duplicates = WholeDF.duplicated(subset=['rs', 'chrom', 'pos', 'SNP_name'], keep='first')
logDF = WholeDF.iloc[np.where(duplicates == True)[0]]
WholeDF = WholeDF.drop(WholeDF.index[np.where(duplicates == True)][0])
否则,只需按照@QuangHoang的建议使用WholeDF.drop_duplicates(inplace=True)