2017-03-04 55 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

相關問題