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

Ame*_*ina 91 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])
Run Code Online (Sandbox Code Playgroud)

如果我对它进行排序,我会默认按升序排序:

> np.sort(temp)
array([2, 2, 2, 4, 4, 4, 4, 6, 7, 7])
Run Code Online (Sandbox Code Playgroud)

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

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

reverse_order = np.sort(temp)[::-1]
Run Code Online (Sandbox Code Playgroud)

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

Pad*_*ham 110

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
Run Code Online (Sandbox Code Playgroud)

  • 使用`a = np.array((...))`成语`a [:: - 1]`不会反转任何东西,它只是对同一数据的_new view_,更具体地说是镜像视图.方法`a [:: - 1] .sort()`**对镜像图像**进行操作,这意味着当`sort`在其镜像图像中移动_left_一个较小的项时,实际上它将它移动到_right_在`a`数组的实内存块中.镜像视图按升序排序,实际数据按降序排序.在家里自己尝试一下,用一些不同的硬币和一面镜子! (37认同)
  • 谢谢,但是`temp [:: - 1] .sort()`怎么知道它必须以相反的顺序排序?我读它的方式是:反转原始数组,然后对其进行排序(按升序排列).为什么要反转原始数组(按随机顺序排列)然后按升序对其进行排序以反转顺序返回数组? (24认同)
  • 这真的应该作为一个可读参数添加,如`np.sort(temp,order ='descending')`而不是要求这些类型的黑客 (18认同)
  • 这看起来很有效,因为`[:: - 1]`只是告诉numpy向后迭代数组,而不是实际重新排序数组.因此,当就地排序发生时,它实际上按升序排序并移动位,但使得向后迭代部分不受影响. (15认同)
  • 是否记录了此行为,因为它非常不直观. (12认同)
  • `[:: - 1]`怎么告诉那个numpy?numpy如何知道在调用对象之前应用的索引?在调用`.sort()之前,是不是`temp [:: - 1]`解决了? (2认同)

Mik*_*nor 75

>>> 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])
Run Code Online (Sandbox Code Playgroud)

  • 最佳答案-简短而甜美,无需了解对其应用了np.sort的axis。 (2认同)
  • 这与 np.sort(temp)[::-1] 不同,它将 nan 放在数组的后面而不是前面。这是好是坏还有待商榷.. (2认同)

Kas*_*mvd 14

对于短数组,我建议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
Run Code Online (Sandbox Code Playgroud)


Meh*_*hdi 13

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

\n

** 请注意,这比我的测试np.flip()更快。np.fliplr()

\n
def sort_reverse(x):\n    return np.sort(x)[::-1]\n\ndef sort_negative(x):\n    return -np.sort(-x)\n\ndef sort_flip(x):\n    return np.flip(np.sort(x)) \n\narr=np.random.randint(1,10000,size=(1,100000))\n\n%timeit sort_reverse(arr)\n%timeit sort_negative(arr)\n%timeit sort_flip(arr)\n
Run Code Online (Sandbox Code Playgroud)\n

结果是:

\n
6.61 ms \xc2\xb1 67.4 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 100 loops each)\n6.69 ms \xc2\xb1 64.7 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 100 loops each)\n6.57 ms \xc2\xb1 58.2 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 100 loops each)\n
Run Code Online (Sandbox Code Playgroud)\n


A. *_*est 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
Run Code Online (Sandbox Code Playgroud)

完全反转

z = x[I[::-1]]
z = -np.sort(-x)
z = np.flip(y)
Run Code Online (Sandbox Code Playgroud)
  • flip改了1.15需要以前的版本。解决办法:。1.14 axispip install --upgrade numpy

一维反转

z = y[::-1]
z = np.flipud(y)
z = np.flip(y, axis=0)
Run Code Online (Sandbox Code Playgroud)

反转的第二维

z = y[::-1, :]
z = np.fliplr(y)
z = np.flip(y, axis=1)
Run Code Online (Sandbox Code Playgroud)

测试

在 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
Run Code Online (Sandbox Code Playgroud)

这主要是由于重新索引而不是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)
Run Code Online (Sandbox Code Playgroud)


ani*_*in4 7

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


Naz*_*Naz 7

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

x=np.sort(array)
y=np.fliplr(x)
Run Code Online (Sandbox Code Playgroud)

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

希望能帮到你!

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