根据值过滤数据框中的几列的最佳方法

时间:2019-07-24 12:37:06

标签: python pandas dataframe

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中?  还是另一个更好的主意?

有人可以帮助我完成这项任务吗?

1 个答案:

答案 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)