python - 为什么 np.unique 在某些情况下没有索引返回会变慢?

标签 python algorithm numpy performance

我注意到如果不将 True 传递给 return_index 参数,在某些情况下 np.unique 可能会变慢。

a = np.ones(shape = (1000, 50), dtype=int)
a[:,-7:] = [10000, -4750, -4750, 95, 95, 95, 95]
arr = np.cumsum(a.ravel())

%timeit np.unique(arr)
%timeit np.unique(arr, return_index=True)
%timeit np.unique(arr, return_index=True, return_inverse=True)
%timeit np.unique(arr, return_index=True, return_inverse=True, return_counts=True)

1.14 ms ± 22.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
711 µs ± 6.78 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
955 µs ± 19.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
1.3 ms ± 143 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

其他类型的数据通常不会出现这种情况。这里发生了什么?

最佳答案

之所以会出现差异,是因为您示例中的数据是排序的。 unique 对数据进行排序,当 return_index=True 时,使用稳定的合并排序算法。当合并排序应用于已排序的数据时,该算法将只遍历一次数据,因此速度非常快。

例如,在下面,arr 是一个非递减值数组:

In [10]: arr = np.random.randint(0, 3, size=50000).cumsum()

In [11]: arr
Out[11]: array([    1,     3,     4, ..., 49892, 49892, 49894])

默认排序算法花费的时间几乎是合并排序算法的 8 倍:

In [12]: %timeit np.sort(arr)
386 µs ± 6.23 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [13]: %timeit np.sort(arr, kind='mergesort')
49.5 µs ± 708 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

您可以在此处查看最终执行查找唯一值实际工作的代码:https://github.com/numpy/numpy/blob/6ff787b93d46cca6d31c370cfd9543ed573a98fc/numpy/lib/arraysetops.py#L320-L361

关于python - 为什么 np.unique 在某些情况下没有索引返回会变慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71260832/

相关文章:

python - 任何想法如何提高从大字符串列表中选择元素的速度

c# - 算法创建层次结构下拉

algorithm - 从几个集合中的每一个中找到包含至少一个元素的最小集合的算法是什么

algorithm - 确定网格上的一个点是否被某种类型的点包围

python - Pandas Groupby 并使用自定义值创建新列

python - 将一列与包含分类值的多列进行比较,无需循环

python - Pandas GroupBy 和计算 Z-Score

math.log 函数中的 python 数学域错误

python - 如何找到椭圆内的点?

Python - csr_matrix 的数据结构