Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在python中更新嵌套列表花费的时间太长_Python_Python 2.7_Python 3.x - Fatal编程技术网

在python中更新嵌套列表花费的时间太长

在python中更新嵌套列表花费的时间太长,python,python-2.7,python-3.x,Python,Python 2.7,Python 3.x,我正在尝试用python实现brown聚类算法 我有cluster=List[List]的数据结构 在任何时候,外部列表长度的最大值为40或41 但内部列表中包含诸如“the”、“hello”等英语单词 因此,我总共有8000个单词(词汇表),最初将前40个单词放入集群 我反复浏览我的词汇表,从41到8000 #做一些计算这需要很少的时间。 #合并列表中的2项并从列表中删除一项 #例:如果c1和c2是集群项目,则 for i in range(41, 8000): clusters.ap

我正在尝试用python实现brown聚类算法

我有cluster=List[List]的数据结构

在任何时候,外部列表长度的最大值为40或41

但内部列表中包含诸如“the”、“hello”等英语单词

因此,我总共有8000个单词(词汇表),最初将前40个单词放入集群

我反复浏览我的词汇表,从41到8000 #做一些计算这需要很少的时间。 #合并列表中的2项并从列表中删除一项 #例:如果c1和c2是集群项目,则

for i in range(41, 8000):
    clusters.append(vocabulary[i])
    c1 = computation 1
    c2 = computation 2
    clusters[c1] = clusters[c1] + clusters[c2]
    del clusters[c2]
但是,随着我对我的词汇表进行迭代,行簇[c1]=簇[c1]+簇[c1]所需的时间逐渐增加。最初,41-50个单词的时间是1秒,但词汇表中每20个单词的时间增长1秒

在我的整个代码中只注释clusters[c1]=clusters[c1]+clusters[c1]时,我观察到所有迭代都需要恒定的时间。我不知道如何加快这一进程

for i in range(41, 8000):
    clusters.append(vocabulary[i])
    c1 = computation 1
    c2 = computation 2
    #clusters[c1] = clusters[c1] + clusters[c2]
    del clusters[c2]
我是stackoverflow的新手,如果这里的格式不正确,请原谅


谢谢

您遇到的问题是列表串联是一个线性时间操作。因此,您的整个循环是
O(n^2)
(这对于
n
来说非常慢,远远大于1000)。这忽略了复制如此大的列表对缓存性能等的不利影响

不相交集数据结构 我推荐的解决方案是使用数据结构。这是一种基于树的数据结构,在执行查询时会“自展平”,从而产生“合并”集群的非常快的运行时

其基本思想是,每个单词从它自己的“单例”树开始,合并簇包括使一棵树的根成为另一棵树的子树。这会重复(注意平衡),直到您拥有所需数量的集群

我编写了一个(GitHub链接),它假设每个集合的元素都是数字。只要你有一个从词汇表术语到整数的映射,它就可以很好地满足你的需要。(注意:我已经做了一些初步测试,但我现在只花了5分钟就完成了,所以我建议检查一下我的工作。
;)

要在代码中使用,我将执行以下操作:

clusters = DisjointSet(8000)
# some code to merge the first 40 words into clusters
for i in range(41, 8000):
    c1 = some_computation() # assuming c1 is a number
    c2 = some_computation() # assuming c2 is a number
    clusters.join(c1, c2)

# Now, if you want to determine if some word with number k is 
# in the same cluster as a word with number j:
print("{} and {} are in the same cluster? {}".format(j, k, clusters.query(j, k))
关于集合与列表 虽然集合提供了比列表更快的访问时间,但它们在复制时的运行时间实际上更差。这在理论上是有意义的,因为一个
集合
对象实际上必须分配和分配比一个列表更多的内存空间来获得适当的负载因子。此外,插入如此多的项可能会导致整个哈希表的“重新哈希”,在最坏的情况下,这是一个二次时间操作

然而,我们现在关心的是实践,所以我做了一个快速的实验来确定偏移量比列表差多少

如果有人感兴趣,执行此测试的代码如下。我使用的是Python的Intel封装,因此我的性能可能比您的计算机稍快一些

import time
import random
import numpy as np
import matplotlib.pyplot as plt

data = []
for trial in range(5):
    trial_data = []

    for N in range(0, 20000, 50):
        l1 = random.sample(range(1000000), N)
        l2 = random.sample(range(1000000), N)
        s1 = set(l1)
        s2 = set(l2)

        # Time to concatenate two lists of length N
        start_lst = time.clock()
        l3 = l1+l2
        stop_lst = time.clock()

        # Time to union two sets of length N
        start_set = time.clock()
        s3 = s1|s2
        stop_set  = time.clock()

        trial_data.append([N, stop_lst - start_lst, stop_set - start_set])
    data.append(trial_data)

# average the trials and plot
data_array = np.array(data)
avg_data = np.average(data_array, 0)

fig = plt.figure()
ax = plt.gca()
ax.plot(avg_data[:,0], avg_data[:,1], label='Lists')
ax.plot(avg_data[:,0], avg_data[:,2], label='Sets')
ax.set_xlabel('Length of set or list (N)')
ax.set_ylabel('Seconds to union or concat (s)')
plt.legend(loc=2)
plt.show()

请提供一段独立的代码,没有未提及的依赖项。首先,您的意思是
clusters[c1]=clusters[c1]+clusters[c2]
?其次,连接列表的速度很慢。您可以将
词汇表
的元素的副本插入到
集群
中,而不是使用原件,然后使用
+=
而不是
+
来执行交替连接,而不是构建新的列表。是的,我的意思是集群[c1]=集群[c1]+集群[c2]。集群[c1]=集群[c1]也将是集群[c1]=集群[c1]+簇[c2]或簇[c1]+=簇[c2]会产生任何性能差异。另外,C2可能是词汇表中不同单词的组合,因此我需要从Copy[C2]中复制项目。我想你可能想考虑使用一个“不相交的集合”数据结构,而不是一个列表来描述你的语料库。它将为并集和集合成员操作提供近似恒定的时间(实际上是反向阿克曼)。今天晚些时候我会写一份更详细的回复。