Python 以降序对numpy数组进行有效排序?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26984414/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 01:15:20  来源:igfitidea点击:

Efficiently sorting a numpy array in descending order?

pythonarrayssortingnumpy

提问by Amelio Vazquez-Reina

I am surprised this specific question hasn't been asked before, but I really didn't find it on SO nor on the documentation of np.sort.

我很惊讶之前没有人问过这个特定的问题,但我真的没有在 SO 和np.sort.

Say I have a random numpy array holding integers, e.g:

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

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

If I sort it, I get ascending order by default:

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

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

but I want the solution to be sorted in descendingorder.

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

Now, I know I can always do:

现在,我知道我总能做到:

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

but is this last statement efficient? Doesn't it create a copy in ascending order, and then reverses this copy to get the result in reversed order? If this is indeed the case, is there an efficient alternative? It doesn't look like np.sortaccepts parameters to change the sign of the comparisons in the sort operation to get things in reverse order.

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

采纳答案by Padraic Cunningham

temp[::-1].sort()sorts the array in place, whereas np.sort(temp)[::-1]creates a new array.

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

回答by Kasramvd

For short arrays I suggest using np.argsort()by finding the indices of the sorted negatived array, which is slightly faster than reversing the sorted array:

对于短数组,我建议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

回答by anishtain4

Unfortunately when you have a complex array, only np.sort(temp)[::-1]works properly. The two other methods mentioned here are not effective.

不幸的是,当你有一个复杂的数组时,只能np.sort(temp)[::-1]正常工作。这里提到的另外两种方法都无效。

回答by Mike O'Connor

>>> 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])

回答by Naz

Hello I was searching for a solution to reverse sorting a two dimensional numpy array, and I couldn't find anything that worked, but I think I have stumbled on a solution which I am uploading just in case anyone is in the same boat.

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

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

np.sort sorts ascending which is not what you want, but the command fliplr flips the rows left to right! Seems to work!

np.sort 按升序排序,这不是您想要的,但命令 fliplr 会从左到右翻转行!似乎工作!

Hope it helps you out!

希望能帮到你!

I guess it's similar to the suggest about -np.sort(-a) above but I was put off going for that by comment that it doesn't always work. Perhaps my solution won't always work either however I have tested it with a few arrays and seems to be OK.

我想它类似于上面关于 -np.sort(-a) 的建议,但我被评论推迟了,因为它并不总是有效。也许我的解决方案也不会总是有效,但是我已经用几个数组对其进行了测试,似乎没问题。

回答by morteza omidipoor

i suggest using this ...

我建议使用这个...

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

for example:

例如:

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

Then your resault:

然后你的结果:

[ 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. ]

回答by A. West

Be careful with dimensions.

小心尺寸。

Let

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

Full Reverse

完全反转

z = x[-I]
z = -np.sort(-x)
z = np.flip(y)
  • flipchanged in 1.15, previous versions 1.14requiredaxis. Solution: pip install --upgrade numpy.
  • flip改了1.15需要以前的版本。解决办法:。1.14axispip install --upgrade numpy

First Dimension Reversed

一维反转

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

Second Dimension Reversed

反转的第二维

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

Testing

测试

Testing on a 100×10×10 array 1000 times.

在 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]        | 4.611778

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

This is mainly due to reindexing rather than argsort.

这主要是由于重新索引而不是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()], xs)
timeit(lambda x: x.sort(), xs)
timeit(lambda x: x.argsort(), xs)
timeit(lambda x: np.flip(x), xs)

回答by maleckicoa

You could sort the array first (Ascending by default) and then apply np.flip()(https://docs.scipy.org/doc/numpy/reference/generated/numpy.flip.html)

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

FYI It works with datetime objects as well.

仅供参考它也适用于日期时间对象。

Example:

例子:

    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])

回答by Don Coder

Here is a quick trick

这是一个快速的技巧

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]