Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 基于对角项的排序矩阵_Python_Sorting_Python 3.x_Numpy_Matrix - Fatal编程技术网

Python 基于对角项的排序矩阵

Python 基于对角项的排序矩阵,python,sorting,python-3.x,numpy,matrix,Python,Sorting,Python 3.x,Numpy,Matrix,首先,我想指出,我的问题与这个不同: 问题如下: 假设我有一个numpy矩阵 A= 5 7 8 7 2 9 8 9 3 我想根据对角线对矩阵进行排序,然后根据它重新排列矩阵元素。以至于现在 sorted_A: 2 9 7 9 3 8 7 8 5 请注意: (1) 。对角线已排序 (2) 。其他元素(非对角线)由其重新调整。怎么用? 因为diag(A)=[5,2,3]&diag(A)=[2,3,5] 因此,行/列索引A=[0,1,2]在排序后的数组中变成[1,2,0] 到目前为止,

首先,我想指出,我的问题与这个不同:

问题如下: 假设我有一个numpy矩阵

A=

5 7 8

7 2 9

8 9 3
我想根据对角线对矩阵进行排序,然后根据它重新排列矩阵元素。以至于现在

sorted_A:

2 9 7

9 3 8

7 8 5
请注意:

(1) 。对角线已排序

(2) 。其他元素(非对角线)由其重新调整。怎么用? 因为diag(A)=[5,2,3]&diag(A)=[2,3,5] 因此,行/列索引A=[0,1,2]在排序后的数组中变成[1,2,0]


到目前为止,我使用蛮力来提取对角线元素,得到索引O(N²),然后重新排列矩阵(另一个O(N²))。我想知道是否有任何有效/优雅的方法来做到这一点。我非常感谢能得到的所有帮助。

根据对角线值对行进行排序很容易:

In [192]: A=np.array([[5,7,8],[7,2,9],[8,9,3]])
In [193]: A
Out[193]: 
array([[5, 7, 8],
       [7, 2, 9],
       [8, 9, 3]])
In [194]: np.diag(A)
Out[194]: array([5, 2, 3])
In [195]: idx=np.argsort(np.diag(A))
In [196]: idx
Out[196]: array([1, 2, 0], dtype=int32)
In [197]: A[idx,:]
Out[197]: 
array([[7, 2, 9],
       [8, 9, 3],
       [5, 7, 8]])
将每行中的元素重新排列到原来的对角线上,然后再回到对角线上,这需要一些实验——反复试验。我们可能必须根据与排序
idx
相关的一些值来“滚动”每一行。我不记得是否有一个单独滚动每一行的函数,或者我们是否需要迭代每一行来实现这一点

In [218]: A1=A[idx,:]
In [219]: [np.roll(a,-i) for a,i in zip(A1,[1,1,1])]
Out[219]: [array([2, 9, 7]), array([9, 3, 8]), array([7, 8, 5])]
In [220]: np.array([np.roll(a,-i) for a,i in zip(A1,[1,1,1])])
Out[220]: 
array([[2, 9, 7],
       [9, 3, 8],
       [7, 8, 5]])
因此,使用
[1,1,1]
完成工作。但我不明白这是怎么得出的。我怀疑我们需要生成更多的测试用例,可能是更大的,并寻找一种模式

滚动可能与行的移动量、原始位置和新位置之间的差异有关。让我们试试:

np.arange(3)-idx

In [222]: np.array([np.roll(a,i) for a,i in zip(A1,np.arange(3)-idx)])
Out[222]: 
array([[2, 9, 7],
       [9, 3, 8],
       [7, 8, 5]])
将排序
idx
应用于行和列似乎也可以做到这一点:

In [227]: A[idx,:][:,idx]
Out[227]: 
array([[2, 9, 7],
       [9, 3, 8],
       [7, 8, 5]])

In [229]: A[idx[:,None],idx]
Out[229]: 
array([[2, 9, 7],
       [9, 3, 8],
       [7, 8, 5]])

在这里,我简化了一个简单的解决方案,这个解决方案以前已经说过了,但很难让您理解

如果要按表的对角线大小对表(例如,混淆矩阵)进行排序,并相应地排列行和列,则此选项非常有用

>>> A=np.array([[5,1,4],[7,2,9],[8,0,3]])
>>> A
array([[5, 1, 4],
   [7, 2, 9],
   [8, 0, 3]])
>>> diag = np.diag(A)
>>> diag
array([5, 2, 3])
>>> idx=np.argsort(diag) # get the order of items that are in diagon
>>> A[idx,:][:,idx]  # reorder rows and arrows based on the order of items on diagon
array([[2, 9, 7],
   [0, 3, 8],
   [1, 4, 5]])

如果您想按降序排序,只需添加
idx=idx[::-1]#逆序

谢谢…但主要问题之一在于重新排列(非对角线元素)部分…(从A中获取“排序的A”矩阵)。此外,在您的回答中,主对角线没有排序:[7,9,8]那么谁来弄明白呢?我认为这不需要太多的
numpy
专业知识,只需要一点普通的问题解决。我只是尝试将排序应用于行和列。你必须看看这是否适用于更一般的情况。使用其他矩阵进行检查(调整“1”向量长度)…它工作正常谢谢。很棒的更新!!!…优雅且快速…感谢无数…你刚刚度过了我的一天…真是太感谢你了…:D…#高兴了你尝试/想出了什么代码?Python当然,我做了什么:(1)获取a=C的diag成员(2)。D=获取已排序C的索引(使用argsort)(3).循环矩阵中的所有元素以根据DH重新调整这与已接受的答案有什么不同吗?已在已接受的答案中说明了答案的每个部分。正如我所提到的,这会从已接受的答案中提取零碎信息,但已接受的答案会使事情变得复杂,因为会到处谈论,不必要的漫无边际。我试着做的是给出一个简单的问题,给出一个简单的答案。没有额外的东西。我明白了。但它仍然没有增加任何东西。我当然感谢你的努力。