如何在列表

时间:2018-03-29 07:59:56

标签: python arrays list

我有一个大约131000个数组的列表,每个数组长度为300.我使用的是python 我想检查这个列表中哪些数组重复。我通过比较每个数组与其他数组来尝试这个。喜欢:

Import numpy as np
wordEmbeddings = [[0.8,0.4....upto 300 elements]....upto 131000 arrays]
count = 0
for i in range(0,len(wordEmbeddings)):
   for j in range(0,len(wordEmbeddings)):
      if i != j:
         if np.array_equal(wordEmbeddings[i],wordEmbeddings[j]):
         count += 1

运行速度非常慢,可能需要数小时才能完成,我怎样才能有效地完成这项工作?

5 个答案:

答案 0 :(得分:5)

您可以使用collections.Counter计算每个子列表的频率

>>> from collections import Counter
>>> Counter(list(map(tuple, wordEmbeddings)))

我们需要将子列表转换为元组,因为列表是不可删除的,即它不能用作dict中的键。

这会给你这样的结果:

>>> Counter({(...4, 5, 6...): 1, (...1, 2, 3...): 1})

此处Counter对象的键是列表,值是此列表出现的次数。接下来,您可以过滤生成的Counter对象,只生成值为>的元素。 1:

>>> items = Counter(list(map(tuple, wordEmbeddings)))
>>> list(filter(lambda x: items[x] > 1,items))

Timeit结果:

$ python -m timeit -s "a = [range(300) for _ in range(131000)]" -s "from collections import Counter" "Counter(list(map(tuple, a)))"
10 loops, best of 3: 1.18 sec per loop

答案 1 :(得分:1)

您可以使用

删除重复的比较
for i in range(0,len(wordEmbeddings)):
    for j in range(i,len(wordEmbeddings)):

您可以查看pypy以获取通用加速功能 也许值得研究以某种方式散列数组。

这是a question on the speeding up np array comparison。元素的顺序对你很重要吗?

答案 2 :(得分:1)

您可以使用settuple查找另一个数组中的重复数组。创建一个包含元组的新列表,我们使用元组,因为列表是不可用的类型。然后使用set过滤新列表。

tuple = list(map(tuple, wordEmbeddings))
duplications = set([t for t in tuple if tuple.count(t) > 1])
print(duplications)

答案 3 :(得分:0)

也许您可以将初始列表缩减为唯一哈希值或非唯一值, 并首先检查哈希 - 这可能是比较元素的更快方法

答案 4 :(得分:0)

我建议你首先对列表进行排序(可能对进一步处理有帮助),然后进行比较。优点是您只需要将每个数组元素与前一个数组元素进行比较:

import numpy as np
from functools import cmp_to_key
wordEmbeddings = [[0.8, 0.4, 0.3, 0.2], [0.2,0.3,0.7], [0.8, 0.4, 0.3, 0.2], [ 1.0, 3.0, 4.0, 5.0]]
def smaller (x,y):
    for i in range(min(len(x), len(y))):
        if x[i] < y[i]:
            return 1
        elif y[i] < x[i]:
            return -1
    if len(x) > len(y):
        return 1
    else:
        return -1
wordEmbeddings = sorted(wordEmbeddings, key=cmp_to_key(smaller))
print(wordEmbeddings)
# output: [[1.0, 3.0, 4.0, 5.0], [0.8, 0.4, 0.3, 0.2], [0.8, 0.4, 0.3, 0.2], [0.2, 0.3, 0.7]]
count = 0
for i in range(1, len(wordEmbeddings)):
    if (np.array_equal(wordEmbeddings[i], wordEmbeddings[i-1])):
        count += 1

print(count)
# output: 1

如果N是单词嵌入的长度,n是内部数组的长度,那么您的方法是进行O(N*N*n)比较。如果在答案中减少比较,那么您仍然可以进行O(N*N*n/2)比较。

排序将花费O(N*log(N)*n)时间,后续的计数步骤只需O(N*n)次,总时间比O(N*N*n/2)