2015-07-11 94 views
3

我想用列表构建一个矩阵,然后用dict的值填充它。它适用于小数据,但当使用更大的数据时计算机崩溃(RAM不足)。 我的脚本显然太重了,但我没有看到如何改进它(首次编程)。由于从一个列表和一个与Python的词典构建一个数组

import numpy as np 
liste = ["a","b","c","d","e","f","g","h","i","j"] 

dico = {"a/b": 4, "c/d" : 2, "f/g" : 5, "g/h" : 2} 

#now i'd like to build a square array (liste x liste) and fill it up with the values of 
# my dict. 


def make_array(liste,dico): 
    array1 = [] 
    liste_i = [] #each line of the array 
    for i in liste: 
     if liste_i : 
      array1.append(liste_i) 
      liste_i = [] 
     for j in liste: 
      if dico.has_key(i+"/"+j): 
       liste_i.append(dico[i+"/"+j]) 
      elif dico.has_key(j+"/"+i): 
       liste_i.append(dico[j+"/"+i]) 
      else : 
       liste_i.append(0) 
    array1.append(liste_i) 
    print array1 
    matrix = np.array(array1) 
    print matrix.shape() 
    print matrix 
    return matrix 

make_array(liste,dico) 

非常感谢,给你答案,使用in dico或列表理解并提高脚本的速度,这是非常有益的。 但似乎我的问题是由下面的函数引起的:

def clustering(matrix, liste_globale_occurences, output2): 
    most_common_groups = [] 
    Y = scipy.spatial.distance.pdist(matrix) 
    Z = scipy.cluster.hierarchy.linkage(Y,'average', 'euclidean') 
    scipy.cluster.hierarchy.dendrogram(Z) 
    clust_h = scipy.cluster.hierarchy.fcluster(Z, t = 15, criterion='distance') 
    print clust_h 
    print len(clust_h) 
    most_common = collections.Counter(clust_h).most_common(3) 
    group1 = most_common[0][0] 
    group2 = most_common[1][0] 
    group3 = most_common[2][0] 
    most_common_groups.append(group1) 
    most_common_groups.append(group2) 
    most_common_groups.append(group3) 
    with open(output2, 'w') as results: # here the begining of the problem 
     for group in most_common_groups: 
      for i, val in enumerate(clust_h): 
       if group == val: 
        mise_en_page = "{0:36s} groupe co-occurences = {1:5s} \n" 
        results.write(mise_en_page.format(str(liste_globale_occurences[i]),str(val))) 

当使用较小的文件,我得到正确的结果,例如:

接触= GROUPE 2

触点b = 2 GROUPE

触点c = GROUPE 2

接触d = GR oupe 2

接触E = GROUPE 3

接触F = GROUPE 3

但是当使用重文件,我只得到每组一个例子:

接触的= groupe 2

contact a = groupe 2

接触的= GROUPE 2

接触= GROUPE 2

接触E = GROUPE 3

接触E = GROUPE 3

+1

你能解释一下*建立一个矩阵列表,然后用字典的值,它填平。*?也许只是展示一个简单的例子! – Kasramvd

+0

不要使用'has_key'它将在2.7中被弃用,并在3中被移除,使用'in dico' –

回答

0

可以创建一个矩阵mat = LEN(清单当然) * len(听)零并通过你的dico和split键:'/'之前的val将是'/'之后的行数和val将是列数。这样你就不需要使用'has_key'搜索功能。

0

您的问题看起来像一个O(n ),因为您想从liste自己获得所有组合。所以你必须有一个内部循环。

你可以尝试做的事情是将每行写入一个文件,然后在新的过程中,从文件中创建矩阵。新进程将使用更少的内存,因为它不需要存储大量输入listedico。因此,像这样:

def make_array(liste,dico): 
    f = open('/temp/matrix.txt', 'w') 
    for i in liste: 
     for j in liste: 
      # This is just short circuit evaluation of logical or. It gets the first value that's not nothing 
      f.write('%s ' % (dico.get(i+"/"+j) or dico.get(j+"/"+i) or 0)) 
     f.write('\n') 
    f.close() 
    return 

然后,一旦这个已经执行了可以拨打

print np.loadtxt('/temp/matrix.txt', dtype=int) 

我已经使用短路评估,以减少您if语句的代码行。事实上,如果你使用list comprehensions您可以make_array功能降低这样的:

def make_array(liste,dico): 
    return np.array([[dico.get(i+"/"+j) or dico.get(j+"/"+i) or 0 for j in liste] for i in liste]) 
相关问题