假设我有一个数组
a = np.array([1, 2, 1, 3, 3, 3, 0])
我如何(高效地,Python 地)找到 a
的哪些元素是重复的(即,非唯一值) ?在这种情况下,如果有效的话,结果可能是 array([1, 3, 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万)上有效。
使用1000万大小的数据集进行测试(在2.8 GHz 至强上) :
a = np.random.randint(10**7, size=10**7)
最快的是排序,1.1秒。可疑的 xor1d
在2.6秒处于第二位,其次是掩蔽和熊猫 Series.duplicated
在3.1秒处,bincount
在5.6秒处,in1d
和 senderle 的 setdiff1d
都在7.3秒处。 Steven 的 Counter
只是稍微慢一点,在10.5秒处; 紧随其后的是 Burhan 的 Counter.most_common
在110秒处,DSM 的 Counter
减法在360秒处。
我将使用性能排序,但是我接受 Steven 的答案,因为性能是可以接受的,而且它的 感觉更清晰,更 Python 化。
编辑: 发现了熊猫的解决方案。如果熊猫是可用的,它的清晰和执行良好。