python – 在维度上按范数对多维NumPy数组进行排序
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了python – 在维度上按范数对多维NumPy数组进行排序,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3434字,纯文字阅读大概需要5分钟。
内容图文
![python – 在维度上按范数对多维NumPy数组进行排序](/upload/InfoBanner/zyjiaocheng/797/4673ad262bcb466ba1149b301e7eeb37.jpg)
我正在使用多维NumPy数组a,它是2×2矩阵的“向量”.
我想排序一个2×2矩阵按行规范排序.
import numpy as np
a = np.array([[[3, 4],
[1, 2]],
[[5, 6],
[7, 8]]])
sortidxs = np.argsort(np.linalg.norm(a, axis=-1))
a = np.array([a[_][sortidxs[_]] for _ in range(a.shape[0])])
# And the final output should be:
print(a)
[[[1 2]
[3 4]]
[[5 6]
[7 8]]]
上面的代码片段做了我想要的(不完全,请看下面的编辑).但我一直在寻找避免循环的方法
a = np.array([a[_][sortidxs[_]] for _ in range(a.shape[0])])
– 编辑 –
上面的例子错过了问题的关键部分.a可能有更多的“空”维度,即
a = np.array([[[3, 4],
[1, 2]],
[[5, 6],
[7, 8]]])
a = a.reshape((2,1,2,2))
现在看起来像:
In [257]: a
Out[257]:
array([[[[3, 4],
[1, 2]]],
[[[5, 6],
[7, 8]]]])
排序后应该是
In [259]: a
Out[259]:
array([[[[1, 2],
[3, 4]]],
[[[5, 6],
[7, 8]]]])
a也可以在开头具有以下尺寸(1,2,2,2)或更多这样的“空”尺寸.我希望这种情况也适用于这些情况.
解决方法:
你可以使用advanced-indexing –
a[np.arange(a.shape[0])[:,None], sortidxs]
样品运行 –
In [144]: a = np.random.randint(0,9,(2,3,4))
In [145]: a
Out[145]:
array([[[1, 1, 5, 5],
[1, 1, 7, 5],
[6, 1, 2, 8]],
[[7, 2, 5, 4],
[3, 7, 3, 7],
[8, 4, 4, 6]]])
In [146]: sortidxs = np.argsort(np.linalg.norm(a, axis=-1))
In [147]: np.array([a[_][sortidxs[_]] for _ in range(a.shape[0])])
Out[147]:
array([[[1, 1, 5, 5],
[1, 1, 7, 5],
[6, 1, 2, 8]],
[[7, 2, 5, 4],
[3, 7, 3, 7],
[8, 4, 4, 6]]])
In [149]: a[np.arange(a.shape[0])[:,None], sortidxs]
Out[149]:
array([[[1, 1, 5, 5],
[1, 1, 7, 5],
[6, 1, 2, 8]],
[[7, 2, 5, 4],
[3, 7, 3, 7],
[8, 4, 4, 6]]])
进一步提升性能
我们可以用np.einsum优化计算sortidxs –
sortidxs = np.einsum('ijk,ijk->ij',a,a).argsort()
让我们来看看并验证这个想法 –
In [94]: a = np.random.randint(0,9,(20,30,40))
In [95]: %timeit np.argsort(np.linalg.norm(a, axis=-1))
10000 loops, best of 3: 63.5 μs per loop
In [96]: %timeit np.einsum('ijk,ijk->ij',a,a).argsort()
10000 loops, best of 3: 19.7 μs per loop
In [97]: a = np.random.randint(0,9,(200,300,400))
In [98]: %timeit np.argsort(np.linalg.norm(a, axis=-1))
10 loops, best of 3: 88.6 ms per loop
In [99]: %timeit np.einsum('ijk,ijk->ij',a,a).argsort()
10 loops, best of 3: 22.6 ms per loop
具有更高尺寸的阵列
对于作为4D数组的附加情况,我们需要使用更多数组进行索引.
1]对于第一轴:使用np.arange(a.shape [0]),最后有两个新轴.
2]对于第二轴:使用np.arange(a.shape [0]),最后一个新轴.
3]对于第三轴:使用sortidxs为其索引.
因此,我们会:
m,n,r,s = a.shape
out = a[np.arange(m)[:,None,None],np.arange(n)[:,None], sortidxs]
单例暗淡的数组(dim,长度= 1)
作为一个特例,假设输入数组的第二个轴已经是单个轴,我们可以简单地使用0作为该轴,从而简化了事情,就像这样 –
a[np.arange(m)[:,None,None],0, sortidxs]
样品运行 –
In [58]: a = np.array([[[3, 4],
...: [1, 2]],
...:
...: [[5, 6],
...: [7, 8]]])
...:
...: a = a.reshape((2,1,2,2))
...:
In [59]: sortidxs = np.argsort(np.linalg.norm(a, axis=-1))
In [60]: a[np.arange(a.shape[0])[:,None,None],0, sortidxs]
Out[60]:
array([[[[1, 2],
[3, 4]]],
[[[5, 6],
[7, 8]]]])
另一个样本运行一个通用形状为(2,3,4)的数组,以使事情变得非常清晰 –
In [70]: a = np.random.randint(0,9,(2,1,3,4))
In [71]: a
Out[71]:
array([[[[6, 4, 8, 6],
[4, 0, 1, 0],
[5, 3, 2, 5]]],
[[[3, 6, 0, 4],
[6, 2, 5, 2],
[0, 8, 0, 8]]]])
In [72]: sortidxs = np.argsort(np.linalg.norm(a, axis=-1))
In [73]: sortidxs
Out[73]:
array([[[1, 2, 0]],
[[0, 1, 2]]])
In [74]: a[np.arange(a.shape[0])[:,None,None],0, sortidxs]
Out[74]:
array([[[[4, 0, 1, 0],
[5, 3, 2, 5],
[6, 4, 8, 6]]],
[[[3, 6, 0, 4],
[6, 2, 5, 2],
[0, 8, 0, 8]]]])
内容总结
以上是互联网集市为您收集整理的python – 在维度上按范数对多维NumPy数组进行排序全部内容,希望文章能够帮你解决python – 在维度上按范数对多维NumPy数组进行排序所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。