关于python:有效地按降序对numpy数组进行排序?

Efficiently sorting a numpy array in descending order?

令我惊讶的是,以前没有提出过这个具体问题,但是我确实没有在SO或np.sort的文档中找到它。

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

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

如果对它进行排序,则默认情况下我将获得升序:

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

但我希望解决方案按降序排序。

现在,我知道我可以永远做:

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

但这最后的陈述有效吗? 它不是按升序创建副本,然后反转此副本以反转顺序获得结果吗? 如果确实如此,是否有有效的选择? 看起来np.sort不能接受参数来更改排序操作中的比较符号,从而以相反的顺序获取内容。


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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


1
2
3
4
5
6
7
>>> 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])


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

1
2
3
4
5
6
7
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]可以正常工作。这里提到的其他两种方法无效。


您好,我在寻找一种对二维numpy数组进行反向排序的解决方案,但找不到任何有效的方法,但是我想我偶然发现了一个我上载的解决方案,以防万一有人在同一条船上。

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

np.sort对升序进行排序,这不是您想要的,但是命令fliplr将行从左向右翻转!似乎可以工作!

希望它可以帮助您!

我猜这与上面关于-np.sort(-a)的建议相似,但是由于评论它并不总是有效而推迟了我的建议。也许我的解决方案也不总是可行,但是我已经用几个阵列对其进行了测试,似乎还可以。


注意尺寸。

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

全反转

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

第一维反转

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

逆向二维

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

测试中

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

1
2
3
4
5
6
7
8
9
10
Method       | Time (ms)
-------------+----------
y[::-1]      | 0.126659  # only in first dimension
-np.sort(-x) | 0.133152
np.flip(y)   | 0.121711
x[-I]        | 4.611778

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 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()], xs)
timeit(lambda x: x.sort(), xs)
timeit(lambda x: x.argsort(), xs)
timeit(lambda x: np.flip(x), xs)


我建议使用这个...

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

例如:

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

然后您的重新库存:

1
2
3
[ 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. ]