有效地按降序排列numpy数组?

时间:2014-11-18 00:16:02

标签: python arrays sorting numpy

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

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

> 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接受参数来改变排序操作中比较的符号,以便以相反的顺序排列。

10 个答案:

答案 0 :(得分:98)

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

答案 1 :(得分:49)

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

答案 2 :(得分:12)

对于短数组,我建议使用def refresh_token(self, username, refresh_token): try: return client.initiate_auth( ClientId=self.client_id, AuthFlow='REFRESH_TOKEN_AUTH', AuthParameters={ 'REFRESH_TOKEN': refresh_token, 'SECRET_HASH': self.get_secret_hash(username) // Note that SECRET_HASH is missing from JSDK // Note also that DEVICE_KEY is missing from my example } ) except botocore.exceptions.ClientError as e: return e.response 查找已排序的否定数组的索引,这比反转已排序的数组要快一些:

np.argsort()

答案 3 :(得分:4)

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

答案 4 :(得分:2)

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

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

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

希望它可以帮助您!

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

答案 5 :(得分:1)

注意尺寸。

让我们

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]
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]        | 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()], xs)
timeit(lambda x: x.sort(), xs)
timeit(lambda x: x.argsort(), xs)
timeit(lambda x: np.flip(x), xs)

答案 6 :(得分:1)

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

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

示例:

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

答案 7 :(得分:1)

这是一个快速的把戏

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]

答案 8 :(得分:1)

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)

答案 9 :(得分:0)

我建议使用此...

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