按降序有效地排序一个数字数组?

我很惊讶这个具体的问题以前没有被问过,但是我真的没有在 SO 或者 np.sort的文档中找到它。

假设我有一个包含整数的随机数字数组,例如:

> temp = np.random.randint(1,10, 10)
> temp
array([2, 4, 7, 4, 2, 2, 7, 6, 4, 4])

如果我对它进行排序,默认情况下会得到升序:

> np.sort(temp)
array([2, 2, 2, 4, 4, 4, 4, 6, 7, 7])

但是我希望解决方案按 正在下降顺序排序。

现在,我知道我总是可以做:

reverse_order = np.sort(temp)[::-1]

但是这最后一个语句是 有效率吗?它是否按升序创建了一个副本,然后反转这个副本以得到相反顺序的结果?如果情况确实如此,是否存在有效的替代方案?看起来 np.sort并不接受参数来更改排序操作中比较的符号,以便按照相反的顺序获取结果。

321639 次浏览

temp[::-1].sort()对数组进行适当的排序,而 np.sort(temp)[::-1]创建一个新数组。

In [25]: temp = np.random.randint(1,10, 10)


In [26]: temp
Out[26]: array([5, 2, 7, 4, 4, 2, 8, 6, 4, 4])


In [27]: id(temp)
Out[27]: 139962713524944


In [28]: temp[::-1].sort()


In [29]: temp
Out[29]: array([8, 7, 6, 5, 4, 4, 4, 4, 2, 2])


In [30]: id(temp)
Out[30]: 139962713524944

对于短数组,我建议使用 np.argsort(),查找排序的负数组的索引,这比反转排序的数组稍快一些:

In [37]: temp = np.random.randint(1,10, 10)


In [38]: %timeit np.sort(temp)[::-1]
100000 loops, best of 3: 4.65 µs per loop


In [39]: %timeit temp[np.argsort(-temp)]
100000 loops, best of 3: 3.91 µs per loop

不幸的是,当你有一个复杂的数组时,只有 np.sort(temp)[::-1]可以正常工作。

>>> a=np.array([5, 2, 7, 4, 4, 2, 8, 6, 4, 4])


>>> np.sort(a)
array([2, 2, 4, 4, 4, 4, 5, 6, 7, 8])


>>> -np.sort(-a)
array([8, 7, 6, 5, 4, 4, 4, 4, 2, 2])

你好,我一直在寻找一个解决方案来反向排序一个二维数组,我没有找到任何工作,但我想我已经无意中发现了一个解决方案,我正在上传,以防有人在同一条船上。

x=np.sort(array)
y=np.fliplr(x)

np.sort对升序排序,这不是您想要的,但是命令 fliplr将行从左向右翻转!好像有用!

希望能帮到你!

我想这和上面关于 -np.sort(-a)的建议很相似,但是我因为评论说它并不总是起作用而放弃了这个想法。也许我的解决方案并不总是有效,但是我已经用几个数组测试过了,似乎没有问题。

我建议用这个..。

np.arange(start_index, end_index, intervals)[::-1]

例如:

np.arange(10, 20, 0.5)
np.arange(10, 20, 0.5)[::-1]

然后你的结果是:

[ 19.5,  19. ,  18.5,  18. ,  17.5,  17. ,  16.5,  16. ,  15.5,
15. ,  14.5,  14. ,  13.5,  13. ,  12.5,  12. ,  11.5,  11. ,
10.5,  10. ]

注意尺寸。

x  # initial numpy array
I = np.argsort(x) or I = x.argsort()
y = np.sort(x)    or y = x.sort()
z  # reverse sorted array

全速后退

z = x[I[::-1]]
z = -np.sort(-x)
z = np.flip(y)
  • flip1.15中改变,以前的版本 1.14 需要 axis。解决方案: pip install --upgrade numpy

一维反转

z = y[::-1]
z = np.flipud(y)
z = np.flip(y, axis=0)

二维反转

z = y[::-1, :]
z = np.fliplr(y)
z = np.flip(y, axis=1)

测试

100 × 10 × 10阵列1000次测试。

Method       | Time (ms)
-------------+----------
y[::-1]      | 0.126659  # only in first dimension
-np.sort(-x) | 0.133152
np.flip(y)   | 0.121711
x[I[::-1]]   | 4.611778


x.sort()     | 0.024961
x.argsort()  | 0.041830
np.flip(x)   | 0.002026

这主要是由于重新索引,而不是 argsort

# Timing code
import time
import numpy as np




def timeit(fun, xs):
t = time.time()
for i in range(len(xs)):  # inline and map gave much worse results for x[-I], 5*t
fun(xs[i])
t = time.time() - t
print(np.round(t,6))


I, N = 1000, (100, 10, 10)
xs = np.random.rand(I,*N)
timeit(lambda x: np.sort(x)[::-1], xs)
timeit(lambda x: -np.sort(-x), xs)
timeit(lambda x: np.flip(x.sort()), xs)
timeit(lambda x: x[x.argsort()[::-1]], xs)
timeit(lambda x: x.sort(), xs)
timeit(lambda x: x.argsort(), xs)
timeit(lambda x: np.flip(x), xs)

您可以首先对数组进行排序(默认情况下为升序) ,然后应用 < strong > np.lip () (https://docs.scipy.org/doc/numpy/reference/generated/numpy.flip.html)

FYI 它同样适用于日期时间对象。

例如:

    x = np.array([2,3,1,0])
x_sort_asc=np.sort(x)
print(x_sort_asc)


>>> array([0, 1, 2, 3])


x_sort_desc=np.flip(x_sort_asc)
print(x_sort_desc)


>>> array([3,2,1,0])

这里有个小窍门

In[3]: import numpy as np
In[4]: temp = np.random.randint(1,10, 10)
In[5]: temp
Out[5]: array([5, 4, 2, 9, 2, 3, 4, 7, 5, 8])


In[6]: sorted = np.sort(temp)
In[7]: rsorted = list(reversed(sorted))
In[8]: sorted
Out[8]: array([2, 2, 3, 4, 4, 5, 5, 7, 8, 9])


In[9]: rsorted
Out[9]: [9, 8, 7, 5, 5, 4, 4, 3, 2, 2]

np.flip()和反向索引基本相同。下面是使用三种不同方法的基准测试。看起来 np.flip()稍微快一点。使用否定较慢,因为它被使用两次,所以反转数组比那快。

* * 根据我的测试,np.flip()np.fliplr()快。

def sort_reverse(x):
return np.sort(x)[::-1]


def sort_negative(x):
return -np.sort(-x)


def sort_flip(x):
return np.flip(np.sort(x))


arr=np.random.randint(1,10000,size=(1,100000))


%timeit sort_reverse(arr)
%timeit sort_negative(arr)
%timeit sort_flip(arr)

结果是:

6.61 ms ± 67.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
6.69 ms ± 64.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
6.57 ms ± 58.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)