Efficiently sorting a numpy array in descending order?
令我惊讶的是,以前没有提出过这个具体问题,但是我确实没有在SO或
假设我有一个包含整数的随机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] |
但这最后的陈述有效吗? 它不是按升序创建副本,然后反转此副本以反转顺序获得结果吗? 如果确实如此,是否有有效的选择? 看起来
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]) |
对于短数组,我建议使用
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 |
不幸的是,当您拥有复杂的数组时,只有
您好,我在寻找一种对二维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 |
这主要是由于重新索引而不是
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. ] |