问题描述
我认为这是在之外最明确的做法numpy
。numpy
如果您担心速度,则必须将其与解决方案放在一起。
>>> 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秒。可疑xor1d
者Series.duplicated
以2.6秒排名第二,其次是面具和熊猫,分别bincount
为3.1秒in1d
和5.6秒,以及哨兵的setdiff1d
两者均为7.3秒。史蒂文的Counter
速度稍慢一点,为10.5秒。紧随其后的是Burhan的Counter.most_common
110年代和DSM的Counter
减法360年代。
我将使用排序来提高性能,但我接受Steven的回答,因为性能是可以接受的,并且 感觉 更加清晰和Pythonic。
编辑:发现了熊猫解决方案。如果有Pandas可用,那就很清楚并且表现良好。