Getting Unique 1D NumPy Array Values without Sorting
我有许多大型1D数组,我想获取唯一的值。通常,可以执行以下操作:
1 2 | x = np.random.randint(10000, size=100000000) np.unique(x) |
但是,这会执行不必??要的数组排序。
1 | set(x) |
但是,这比用
如果您的值是相对较小范围内的正整数(例如0 ... 10000),则有另一种方法可以使用掩码获取唯一值列表:
(请参见下面的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import numpy as np def unique1(x): return np.unique(x) def unique2(x): maxVal = np.max(x)+1 values = np.arange(maxVal) used = np.zeros(maxVal) used[x] = 1 return values[used==1] # optimized (with option to provide known value range) def unique3(x,maxVal=None): maxVal = maxVal or np.max(x)+1 used = np.zeros(maxVal,dtype=np.uint8) used[x] = 1 return np.argwhere(used==1)[:,0] |
在我的测试中,此方法比np.unique快很多,并且不涉及排序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | from timeit import timeit count = 3 x = np.random.randint(10000, size=100000000) t = timeit(lambda:unique1(x),number=count) print("unique1",t) t = timeit(lambda:unique2(x),number=count) print("unique2",t) t = timeit(lambda:unique3(x),number=count) print("unique3",t) t = timeit(lambda:unique3(x,10000),number=count) print("unique3",t,"with known value range") # unique1 16.894681214000002 # unique2 0.8627655060000023 # unique3 0.8411087540000004 # unique3 0.5896318829999991 with known value range |
以防万一您改变了对依赖关系的主意,这是一个非常简单的
1 2 3 4 5 6 7 8 9 10 11 12 | import numba @numba.njit def unique(arr): return np.array(list(set(arr))) %timeit unique(x) #using Alain T.'s benchmark array 2.64 s ± 799 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) %timeit np.unique(x) 5.45 s ± 233 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) |
闪电般的速度不如上面,但也不需要正整数输入。