我正在尝试使用列表构建矩阵,然后用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
答案 0 :(得分:0)
你可以创建一个零的矩阵mat = len(liste)* len(liste)并通过你的dico和split键:val之前的' /'将是' /'之后的行数和数量将是列数。这样你就不需要使用'has_key'搜索功能。
答案 1 :(得分:0)
您的问题看起来像是O(n 2 ),因为您希望从liste
获取所有组合。所以你必须有一个内循环。
您可以尝试做的是将每一行写入文件,然后在新的过程中,从文件中创建矩阵。新流程会占用更少的内存,因为它不会存储liste
和dico
的大量输入。所以像这样:
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])