检查python列表/numpy ndarray中是否存在重复项的最快方法 [英] Fastest way to check if duplicates exist in a python list / numpy ndarray

查看:37
本文介绍了检查python列表/numpy ndarray中是否存在重复项的最快方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想确定我的列表(实际上是numpy.ndarray)是否在尽可能快的执行时间内包含重复项。请注意,我不在乎是否删除重复项,我只想知道是否有重复项。

注意:如果这不是复制品,我会非常惊讶,但我已经尽力了,但找不到。最接近的是this questionthis question,这两个都请求返回唯一列表。

推荐答案

以下是我想到的四种方法。

TL;DR:如果您期望的重复数很少(小于1/1000):

def contains_duplicates(X):
    return len(np.unique(X)) != len(X)

如果您希望频繁(超过1/1000)重复:

def contains_duplicates(X):
    seen = set()
    seen_add = seen.add
    for x in X:
        if (x in seen or seen_add(x)):
            return True
    return False

第一个方法是从要返回唯一值的this answer提前退出,第二个方法与应用于this answer的想法相同。

>>> import numpy as np
>>> X = np.random.normal(0,1,[10000])
>>> def terhorst_early_exit(X):
...:     elems = set()
...:     for i in X:
...:         if i in elems:
...:             return True
...:         elems.add(i)
...:     return False
>>> %timeit terhorst_early_exit(X)
100 loops, best of 3: 10.6 ms per loop
>>> def peterbe_early_exit(X):
...:     seen = set()
...:     seen_add = seen.add
...:     for x in X:
...:         if (x in seen or seen_add(x)):
...:             return True
...:     return False
>>> %timeit peterbe_early_exit(X)
100 loops, best of 3: 9.35 ms per loop
>>> %timeit len(set(X)) != len(X)
100 loops, best of 3: 4.54 ms per loop
>>> %timeit len(np.unique(X)) != len(X)
1000 loops, best of 3: 967 µs per loop

如果您从普通的Python列表开始,而不是numpy.ndarray

,会有什么变化吗?
>>> X = X.tolist()
>>> %timeit terhorst_early_exit(X)
100 loops, best of 3: 9.34 ms per loop
>>> %timeit peterbe_early_exit(X)
100 loops, best of 3: 8.07 ms per loop
>>> %timeit len(set(X)) != len(X)
100 loops, best of 3: 3.09 ms per loop
>>> %timeit len(np.unique(X)) != len(X)
1000 loops, best of 3: 1.83 ms per loop

编辑:如果我们预先预期重复数怎么办?

以上比较是在假设a)很可能没有重复的情况下进行的,或者b)我们更担心最坏的情况而不是平均情况。

>>> X = np.random.normal(0, 1, [10000])
>>> for n_duplicates in [1, 10, 100]:
>>>     print("{} duplicates".format(n_duplicates))
>>>     duplicate_idx = np.random.choice(len(X), n_duplicates, replace=False)
>>>     X[duplicate_idx] = 0
>>>     print("terhost_early_exit")
>>>     %timeit terhorst_early_exit(X)
>>>     print("peterbe_early_exit")
>>>     %timeit peterbe_early_exit(X)
>>>     print("set length")
>>>     %timeit len(set(X)) != len(X)
>>>     print("numpy unique length")
>>>     %timeit len(np.unique(X)) != len(X)
1 duplicates
terhost_early_exit
100 loops, best of 3: 12.3 ms per loop
peterbe_early_exit
100 loops, best of 3: 9.55 ms per loop
set length
100 loops, best of 3: 4.71 ms per loop
numpy unique length
1000 loops, best of 3: 1.31 ms per loop
10 duplicates
terhost_early_exit
1000 loops, best of 3: 1.81 ms per loop
peterbe_early_exit
1000 loops, best of 3: 1.47 ms per loop
set length
100 loops, best of 3: 5.44 ms per loop
numpy unique length
1000 loops, best of 3: 1.37 ms per loop
100 duplicates
terhost_early_exit
10000 loops, best of 3: 111 µs per loop
peterbe_early_exit
10000 loops, best of 3: 99 µs per loop
set length
100 loops, best of 3: 5.16 ms per loop
numpy unique length
1000 loops, best of 3: 1.19 ms per loop

因此,如果您期望的重复项很少,则numpy.unique函数是可行的。随着预期重复数的增加,早期退出方法占主导地位。

这篇关于检查python列表/numpy ndarray中是否存在重复项的最快方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆