【发布时间】:2018-08-07 18:02:39
【问题描述】:
我是一名试图验证实验的生物学家。在我的实验中,我在特定治疗后发现了 71 个突变。为了确定这些突变是否真的是由于我的治疗,我想将它们与一组随机生成的突变进行比较。有人建议我可能会尝试生成一百万组 71 个随机突变进行统计比较。
首先,我有一个数据框,其中包含感兴趣的基因组中的 7000 个基因。我知道他们的开始和结束位置。数据框的前五行如下所示:
transcript_id protein_id start end kogClass
0 g2.t1 695054 1 1999 Replication, recombination and repair
1 g3.t1 630170 2000 3056 General function prediction only
2 g5.t1 695056 3057 4087 Signal transduction mechanisms
3 g6.t1 671982 4088 5183 N/A
4 g7.t1 671985 5184 8001 Chromatin structure and dynamics
现在大约有 71 个随机突变的百万组:我编写了一个调用一百万次的函数,它似乎效率不高,因为 4 小时后它只完成了 1/10。这是我的代码。如果有人能提出一种加快速度的方法,我会欠你一杯啤酒!我的感激之情。
def get_71_random_genes(df, outfile):
# how many nucleotides are there in all transcripts?
end_pos_last_gene = df.iloc[-1,3]
# this loop will go 71 times
for i in range(71):
# generate a number from 1 to the end of all transcripts
random_number = randint(1, end_pos_last_gene)
# this is the boolean condition - checks which gene a random number falls within
mask = (df['start'] <= random_number) & (df['end'] >= random_number)
# collect the rows that match
data = df.loc[mask]
# write data to file.
data.to_csv(outfile, sep='\t', index=False, header=False)
【问题讨论】:
-
一个重要因素可能是
data.to_csv():您打开和关闭文件 71,000,000 次,由于 I/O 是最慢的操作之一,我猜这是一个巨大的瓶颈。 -
这是有道理的。有什么更好的方法?构建一个包含 71,000,000 行的大型 df,然后将其写入文件?我认为我可怜的笔记本电脑会崩溃。也许是一本字典?
-
一个快速的解决方法就是在循环之后调用
to_csv,而不是在循环内。 I/O 减少了 71 倍。绝对不想要 71e6 Pandas 专栏,那是灾难的根源。 :( 我会说,将你可以存储的内容存储在 Numpy 数组中,也许每 10,000 组然后写出数组并刷新它。 -
@ juanpa.arrivillaga - 在大多数情况下,每一行都是一个独特的基因。但是有些基因带有多个“kogClass”注释,布尔掩码返回多行。每个 random_number 旨在模拟单核苷酸多态性,或 DNA 序列的一个字符的变化。掩码旨在找到该序列所属的基因范围。也许最好删除重复的基因并选择 71 个随机行?你会如何建议这样做?我是初学者,请解释一下!
-
@juanpa.arrivillaga 第一个版本大约一个小时,第二个版本大约 15 分钟。
标签: python performance pandas dataframe indexing