2017-03-04 60 views
1

我有一个用下面的代码如何使用多处理模块迭代列表并将其与字典中的键匹配?

infile= open(sys.argv[1], "r") 
lines = infile.readlines()[1:] 
master_lst = ["read"] 
for line in lines: 
line= line.strip().split(',') 
fourth_field = line [3] 
master_lst.append(fourth_field) 

此主列表具有一套独特的序列命名从CSV文件创建master_lst列表。现在,我必须循环30个折叠的FASTA文件来计算主列表中每个这些序列的出现次数。 30个的文件的文件格式如下:

>AAAAAAAAAAAAAAA 
7451 
>AAAAAAAAAAAAAAAA 
4133 
>AAAAAAAAAAAAAAAAA 
2783 

用于计数出现的次数,我通过每个文件30的循环和创建与作为键和出现作为值的数字序列的字典。然后我迭代master_lst的每个元素,并将其与上一步创建的字典中的键匹配。如果有匹配,我将密钥的值附加到新列表(ind_lst)。如果没有,我将0附加到ind_lst。造成这种情况的代码如下:

for file in files: 
ind_lst = [] 
if file.endswith('.fa'): 
    first = file.split(".") 
    first_field = first [0] 
    ind_lst.append(first_field) 
    fasta= open(file) 
    individual_dict= {} 
    for line in fasta: 
    line= line.strip() 
    if line == '': 
    continue 
    if line.startswith('>'): 
    header = line.lstrip('>') 
    individual_dict[header]= '' 
    else: 
    individual_dict[header] += line 
    for key in master_lst[1:]: 
    a = 0 
    if key in individual_dict.keys(): 
    a = individual_dict[key] 
    else: 
    a = 0 
    ind_lst.append(a) 

然后我写的master_lst到CSV文件,并ind_lst使用代码在这里解释说:How to append a new list to an existing CSV file?

最终的输出应该是这样的:

Read       file1  file2 so on until file 30 
AAAAAAAAAAAAAAA     7451  4456 
AAAAAAAAAAAAAAAA    4133  3624 
AAAAAAAAAAAAAAAAA    2783  7012 

当我使用较小的master_lst时,此代码工作得很好。但是当master_lst的大小增加时,执行时间会增加太多。 master_lst我现在正在使用的有35,718,501个序列(元素)。当我将50个序列分组并运行代码时,该脚本需要2个小时才能执行。因此,对于35,718,501个序列,需要永久完成。

现在我不知道如何加快脚本。我不太确定是否可以对此脚本进行一些改进,使其在更短的时间内执行。我在一个有16个CPU核心的Linux服务器上运行我的脚本。当我使用命令顶部时,我可以看到脚本只使用一个CPU。但我不是python的专家,我不知道如何使用多处理模块在所有可用的CPU内核上运行它。我检查了这个网页:Learning Python's Multiprocessing Module

但是,我不太确定defif __name__ == '__main__':下应该有什么。我也不太确定我应该传递给这个函数。我得到当我尝试从道格拉斯第一代码中的错误,不传递任何参数如下:

File "/usr/lib/python2.7/multiprocessing/process.py", line 114, in run 

self._target(*self._args, **self._kwargs) 

我一直为这最后的几天,我还没有在我的生成所需的输出是成功的。如果任何人都可以建议一个可以快速运行的替代代码,或者如果有人可以建议如何在多个CPU上运行此代码,那将非常棒。任何帮助解决这个问题将不胜感激。

回答

1

这是一个多处理版本。它使用的方法与您在代码中的做法略有不同,因为它不需要创建ind_lst

差异的本质是它首先产生所需数据的转置,然后将其转置为所需的结果。

换句话说,而不是直接创建此:

Read,file1,file2 
AAAAAAAAAAAAAAA,7451,4456 
AAAAAAAAAAAAAAAA,4133,3624 
AAAAAAAAAAAAAAAAA,2783,7012 

它首先生产:

Read,AAAAAAAAAAAAAAA,AAAAAAAAAAAAAAAA,AAAAAAAAAAAAAAAAA 
file1,7451,4133,2783 
file2,4456,3624,7012 

...然后调换与内置zip()功能以获得所需的格式。

除了不需要创建ind_lst,它还允许为每个文件创建一行数据,而不是创建一列(这样更容易,而且可以用更少的工作更高效地完成)。

下面的代码:

+0

谢谢你这么多,显示如何使用多进程module.Thank你这么多时间和精力解决问题。我对前面的脚本进行了分析,但我不太确定如何找到确切的瓶颈。当我终于找到时,它是for循环之后的if语句,这是有问题的。我尝试了一个使用熊猫数据框的不同解决方案(没有多处理)。我接近解决我的问题,我也得到了你的答案。谢谢:)我是一位最近开始学习Python的生物学家,但肯定会将您对脚本编写的评论整合到 – rex

+0

不客气。我怀疑你在生物信息学工作,所以决定伸出援助之手。坦率地说,我不知道它是否比使用多处理更快,因为我没有用于进行测量的实际数据文件。如果主列表非常庞大,它可能会有问题,因为它将其副本传递给每个子任务。启动时,每个子任务都可以通过文件从文件中读取,从而解决此问题。这就是说,如果它回答你的问题,请考虑接受它。请参阅[_当某人回答我的问题时该怎么办?_(http://url.com/help/someone-answers) – martineau

+0

@rex:这种多处理方法是否更快? – martineau

相关问题