我想过滤一个巨大的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()
吗?
答案 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
中的相应值。这充当groupby
和sum
。通过随后使用f
对结果进行切片,我们有效地得到groupby
,transform
,sum
。这比你正在做的transform
快得多。