使用Python从列表和字典构建数组

时间:2015-07-11 10:25:52

标签: python arrays list dictionary matrix

我正在尝试使用列表构建矩阵,然后用dict的值填充它。它适用于小数据但是当使用更大的数据时计算机崩溃(不够Ram)。 我的剧本显然太沉重但我不知道如何改进它(第一次编程)。感谢

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)))

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

  

联系a = groupe 2

     

联系b = groupe 2

     

联系c = groupe 2

     

联系d = groupe 2

     

联系e = groupe 3

     

联系f = groupe 3

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

  

联系a = groupe 2

     

联系a = groupe 2

     

联系a = groupe 2

     

联系a = groupe 2

     

联系e = groupe 3

     

联系e = groupe 3

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

您的问题看起来像是O(n 2 ),因为您希望从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])