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

Posted

技术标签:

【中文标题】使用 Python 从列表和字典构建数组【英文标题】:Build An Array from a list and a dictionnary with Python 【发布时间】:2015-09-30 02:40:44 【问题描述】:

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

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

【问题讨论】:

您能否详细解释一下用列表构建矩阵,然后用dict 的值填充它。?也许展示一个最小的例子! 不要使用has_key它在2.7中被弃用并在3中删除,使用in dico 【参考方案1】:

您可以创建一个零矩阵 mat=len(liste)*len(liste) 并检查您的 dico 和拆分键:'/' 之前的 val 将是行数,而 '/' 之后的 val 将是行数柱子。这样就不需要使用'has_key'搜索功能了。

【讨论】:

【参考方案2】:

您的问题看起来像一个 O(n2) 因为您想从 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])

【讨论】:

以上是关于使用 Python 从列表和字典构建数组的主要内容,如果未能解决你的问题,请参考以下文章

Python:从两个列表构建字典[重复]

在 Python 循环中构建字典 - 列表和字典理解

在使用 Python 从字典列表和相应计数中提取键列表时需要帮助

python的列表推导式字典推导式集合推导式

将字典数组传递给python

python的各种推导式(列表推导式字典推导式集合推导式)