确定数组中的重复值

问题描述

我认为这是在之外最明确的做法numpynumpy如果您担心速度,则必须将其与解决方案放在一起。

>>> import numpy as np
>>> from collections import Counter
>>> a = np.array([1, 2, 1, 3, 3, 3, 0])
>>> [item for item, count in Counter(a).items() if count > 1]
[1, 3]

注意: 这与Burhan Khalid的答案类似,但items在这种情况下不带下标的使用应更快。

解决方法

假设我有一个数组

a = np.array([1,2,1,3,0])

如何(有效地,以Python方式)找到a重复的元素(即非唯一值)?在这种情况下,结果将是有效的,array([1,3])或者可能array([1,3])是有效的。

我想出了一些可行的方法:

掩蔽

m = np.zeros_like(a,dtype=bool)
m[np.unique(a,return_index=True)[1]] = True
a[~m]

设定操作

a[~np.in1d(np.arange(len(a)),np.unique(a,return_index=True)[1],assume_unique=True)]

这个很可爱,但可能是非法的(a实际上并不是唯一的):

np.setxor1d(a,np.unique(a),assume_unique=True)

直方图

u,i = np.unique(a,return_inverse=True)
u[np.bincount(i) > 1]

排序

s = np.sort(a,axis=None)
s[:-1][s[1:] == s[:-1]]

大熊猫

s = pd.Series(a)
s[s.duplicated()]

有什么我想念的吗?我不一定要寻找仅numpy的解决方案,但它必须与numpy数据类型一起使用,并且必须在中等大小的数据集(最大1000万个大小)上有效。


结论

使用一千万个大小的数据集(在2.8GHz Xeon上)进行测试:

a = np.random.randint(10**7,size=10**7)

最快的是排序,速度为1.1秒。可疑xor1dSeries.duplicated以2.6秒排名第二,其次是面具和熊猫,分别bincount为3.1秒in1d和5.6秒,以及哨兵的setdiff1d两者均为7.3秒。史蒂文的Counter速度稍慢一点,为10.5秒。紧随其后的是Burhan的Counter.most_common110年代和DSM的Counter减法360年代。

我将使用排序来提高性能,但我接受Steven的回答,因为性能是可以接受的,并且 感觉 更加清晰和Pythonic。

编辑:发现了熊猫解决方案。如果有Pandas可用,那就很清楚并且表现良好。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...