通过不同的分组列过滤大型pandas DataFrame的快速方法?

时间:2017-09-08 04:27:27

标签: python pandas numpy dataframe

我想过滤一个巨大的python pandas数据帧。表格中有四列。

FLAT_DF.head() 
---

chr     loc     cell                    reads
1       6458    TCTTTCCTCACGGTTA        1
1       6459    TCTTTCCTCACGGTTA        1
1       6460    TCTTTCCTCACGGTTA        1
1       6461    TCTTTCCTCACGGTTA        3
1       6462    TCTTTCCTCACGGTTA        1
1       6463    TCTTTCCTCACGGTTA        1
1       6464    TCTTTCCTCACGGTTA        1
1       6465    TCTTTCCTCACGGTTA        1
1       6914    GGGCACTTCGGAAATA        1
1       6914    ACGATGTTCAGTTAGC        1
1       6914    CGACTTCGTTGTACAC        1
1       6914    AACTGGTCACGCTTTC        1
1       6914    TGTTCCGTCGTTTAGG        1
1       6914    GACTGCGGTGTTTGGT        2
1       6914    AGCTCCTTCCACGACG        1

我尝试通过一组复杂的规则来过滤数据框。

FILTERED_DF = FLAT_DF[
    # filter cell with enough coverage
    (FLAT_DF.groupby('cell').reads.transform(lambda x: x.sum()) > 10000) &
    # filter cell has informative site
    (FLAT_DF.groupby('cell').reads.transform(lambda x: (x > 5).sum()) > 10) &
    # filter site has informative cell
    (FLAT_DF.groupby(['chm', 'loc']).reads.transform(lambda x: (x > 1).sum()) > 10)
    ].reset_index()

上面的代码在样本数据上工作正常,但在过滤整个表时需要很长时间才能完成。 有没有更好的方法来实现它?我可以改用np.where()吗?

1 个答案:

答案 0 :(得分:4)

我会使用numpy.bincount

以这种方式构建它
f, u = pd.factorize(df.cell.values)
g, t = pd.factorize(list(zip(df.chr.values.tolist(), df['loc'].values.tolist())))

r = df.reads.values

cond1 = (np.bincount(f, r) > 10000)[f]
cond2 = (np.bincount(f, r > 5) > 10)[f]
cond3 = (np.bincount(g, r > 1) > 10)[g]
cond4 = (np.bincount(f) > 1000)[f]

df[cond1 & cond2 & cond3 & cond4]

解释

  • pd.factorize返回可散列事物数组的整数分解。在f, u的情况下,我们将'cell'列分解。 u是唯一的单元格值(我们在这里不需要)
  • np.bincount计算" bin"的次数。引用并告诉我们每个唯一单元格在'cell'列中显示的次数如果我们刚刚传递了f参数。但是我们没有,我们也通过r这是weights参数。每次" bin"而不是递增1。遇到f,我们会增加r中的相应值。这充当groupbysum。通过随后使用f对结果进行切片,我们有效地得到groupbytransformsum。这比你正在做的transform快得多。
  • 其他条件和因子分解遵循相同的逻辑。