我有一个numpy数组,我想检查它是否已排序。
>>> a = np.array([1,2,3,4,5])
array([1, 2, 3, 4, 5])
答案 0 :(得分:20)
使用NumPy工具:
np.diff(a)>=0
但是numpy解决方案都是O(n)。
如果你想快速编写代码并在非排序数组上快速得出结论:
import numba
@numba.jit
def is_sorted(a):
for i in range(a.size-1):
if a[i+1] < a[i] :
return False
return True
在随机数组上是O(1)。
答案 1 :(得分:12)
np.all(a[:-1] <= a[1:])
示例:
is_sorted = lambda a: np.all(a[:-1] <= a[1:])
>>> a = np.array([1,2,3,4,9])
>>> is_sorted(a)
True
>>> a = np.array([1,2,3,4,3])
>>> is_sorted(a)
False
答案 2 :(得分:1)
低效但易于解决的解决方案:
(a == np.sort(a)).all()
答案 3 :(得分:0)
为完整性起见,下面找到O(log n)迭代解决方案。递归版本速度较慢,向量大小较大时会崩溃。但是,由于现代CPU优化,它仍然比使用np.all(a[:-1] <= a[1:])
的本地numpy慢。 O(log n)更快的唯一情况是“平均”随机情况或“几乎”排序。如果您怀疑阵列已经完全排序,那么np.all会更快。
def is_sorted(a):
idx = [(0, a.size - 1)]
while idx:
i, j = idx.pop(0) # Breadth-First will find almost-sorted in O(log N)
if i >= j:
continue
elif a[i] > a[j]:
return False
elif i + 1 == j:
continue
else:
mid = (i + j) >> 1 # Division by 2 with floor
idx.append((i, mid))
idx.append((mid, j))
return True
is_sorted2 = lambda a: np.all(a[:-1] <= a[1:])
以下是结果:
# Already sorted array - np.all is super fast
sorted_array = np.sort(np.random.rand(1000000))
%timeit is_sorted(sorted_array)
659 ms ± 3.28 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit is_sorted2(sorted_array)
431 µs ± 35.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
# Here I included the random in each command so we need to substract it's timing
%timeit np.random.rand(1000000)
6.08 ms ± 17.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit is_sorted(np.random.rand(1000000))
6.11 ms ± 58.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
# Without random part, it took 6.11 ms - 6.08 ms = 30µs per loop
%timeit is_sorted2(np.random.rand(1000000))
6.83 ms ± 75.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
# Without random part, it took 6.83 ms - 6.08 ms = 750µs per loop
Net,除非要运行超过1亿个元素数组,否则O(n)向量优化的代码要比O(log n)算法要好。