2016-02-26 112 views
0

腳本基本上是根據他們借用的書籍(代碼)來衡量學生之間的關係。所以我使用ete2包爲不同類型的書建立了一棵樹。現在我試圖編寫一段代碼,它從樹和一個csv文件中獲取數據,並通過函數關係進行一些數據分析.csv文件包含超過50,000行。問題是需要很長時間才能運行代碼(大約7天),而它只使用我的計算機CPU和內存的10%到20%。花費太長時間來運行python腳本

這是我用過的CSV文件的一個例子:

ID Code Count 
1 A1... 6 
1 A2... 5 
2 A.... 4 
2 D.... 1 
2 A1... 2 
3 D.... 5 
3 D1... 3 
3 D2... 5 

下面是代碼:

from ete2 import Tree 
import pandas as pd 
import numpy as np 
from __future__ import division 
import math 


data= pd.read_csv('data.csv', names=['ID','Code', 'Count']) 
codes_list= list (set(data['Code'])) 
total_codes= data.shape[0] 
students_list= list (set(data['ID'])) 



#################################### 


# generate the tree 
t = Tree (".....;", format =0) 
for i in codes_list: 
    if '....' in i: 
     node = t.search_nodes(name = '.....') 
     node[0].add_child(name= i) 
for i in codes_list: 
    if '...' in i and '....' not in i: 
     if i[0]+'....' in codes_list: 
      node = t.search_nodes(name = i[0]+'....') 
      node[0].add_child(name= i) 
     else: 
      node = t.search_nodes(name = '.....') 
      node[0].add_child(name= i) 

# save the tree in a file 
t.write(outfile= file_path + "Codes_tree.nh", format =3) 
return t.get_ascii(show_internal=True) 

#################################### 

def relationship(code1,code2): 

    code1_ancestors= t.search_nodes(name=code1)[0].get_ancestors() 
    code2_ancestors=t.search_nodes(name=code2)[0].get_ancestors(
    common_ancestors = [] 
    for a1 in code1_ancestors: 
     for a2 in code2_ancestors: 
      if a1==a2: 
       common_ancestors.append(a1) 
    IC_values = [] 
    for ca in common_ancestors: 
     code_descendants=[] 
     for gd in ca.get_descendants(): 
      code_descendants.append(gd.name) 
     code_descendants.append(ca) 
     frequency= 0 
     for k in code_descendants: 
       frequency= frequency + code_count.Count[k] 

     IC = - (math.log (frequency/float (total_codes))) 
     IC_values.append (IC) 

    IC_max= max(IC_values) 
    return IC_max 

################## 

relationship_matrix = pd.DataFrame(index=[students_list], columns=[students_list]) 
for student in students_list: 
p1= list (self.data.Code[data.ID==student]) 
for student1 in students_list: 
    p2= list data.Code[data.PID==student1]) 
    student_l=[] 
    for l in p1: 
     for m in p2: 
      student_l.append(relationship(l,m)) 

    max_score = np.max(np.array(student_l).astype(np.float)) 
    relationship_matrix.loc[student,student1] = max_score 

print relationship_matrix 

回答

0

有一些「最佳化」你能做到,這裏有幾個例子我可以快速找到(假設code1_ancestorscode2_ancestors等都是列表或等價的東西):

common_ancestors = [] 
for a1 in code1_ancestors: 
    for a2 in code2_ancestors: 
     if a1==a2: 
      common_ancestors.append(a1) 

可製成方式,通過更快:

set(code1_ancestors)&set(code2_ancestors) 

,並提到你的for循環實際上可以與共同祖先的副本結束。

或者這樣:

code_descendants = [gf.name for in ca.get_descendants()] 

或者這也:

code_descendants=[] 
for gd in ca.get_descendants(): 
    code_descendants.append(gd.name) 

可以通過提高

frequency= 0 
for k in code_descendants: 
     frequency= frequency + code_count.Count[k] 

可轉向:

frequency = code_count.loc[code_descendants, "Count"].sum() 

基本上儘量避免迭代操作,即for循環,並嘗試使用完整的numpy數組(熊貓數據框架的基礎結構)完成操作。

+0

這些編輯真正的幫助,我已經做了,其餘不變。儘管它減少了處理時間,但仍需要很長時間才能運行。爲什麼它不使用所有的內存資源!爲什麼只有15%? – goodX

+0

也許這就是它需要的所有內存?順便說一下,當你說CPU使用率是指單核CPU使用率還是一般系統負載?還有一些提示。使用'timeit'來識別代碼的緩慢部分。另外,在我看來,您可以並行批處理csv文件,然後將結果合併在一起。看看['multiprocessing'](https://docs.python.org/2/library/multiprocessing.html)。並且不要忘記投票/接受答案,如果它有助於解決你的問題:)。 –

0

我沒有看到Tree類的聲明,但在前兩行關係()中引用了一個。

你應該得到一個「NameError:名字‘T’沒有定義」

+0

抱歉。我剛剛添加了樹的代碼。 – goodX