2016-04-03 7 views
3

まず私の質問がより異なっていることを1本:Sort a numpy matrix based on its diagonalソート行列は、私が指摘したいすべての

質問は以下の通りである:私は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(sorted_A)= [2,3,5] したがって、行/列インデックスA = [0,1,2]は[1,2,0] in sorted_A。

これまでは、対角要素を抽出し、インデックスO(N²)を取得してから、マトリックス(別のO(N²))を再配置するブルートフォースを使用します。私はこれを行うための効率的な/エレガントな方法があるのだろうかと思います。私が得ることができるすべての助けに感謝します。対角の値に基づいて行をソート

+0

を追加あなたはどのコードを試してみたのですか? – cctan

+0

Python ofcourse、私は何をしましたか: (1)A = Cのdiagメンバーを取得してください (2)D =ソート済みCのインデックスを取得する(argsortを使用) 。D –

答えて

1

は容易である:元の対角線に、各行の要素を再配置

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]を実行します。しかし、私はそれをどのように導き出すことができないのか分かりません。私はいくつかのより多くのテストケースを生成する必要があると思われます。より大きなテストケースを作成し、パターンを探す必要があります。

このロールは、元の位置と新しい位置の差である行の移動量と関係している可能性があります。試してみましょう:行と列の両方に並べ替えidxを適用

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

は、同様にトリックを行うようだ:

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

に基づいて再調整するために行列内のすべての要素をループしてくださいありがとう...しかし、主な問題の1つは、再配置(非対角要素)部分にあります(Aから "sorted_A"行列を得る) 。 さらに、あなたの答えでは、メインの対角線はソートされていません:[7,9,8] –

+0

誰がそれを理解しようとしていますか?私はそれが多くの普通の問題解決のちょっとした知識を必要としないと思う。 – hpaulj

+0

助けてくれてありがとう... –

0

ここで私は前に述べた簡単な解決策を簡素化するが、入手困難ですあなたの頭の周り。

あなたはその対角線の大きさ(例えば混同行列をテーブルをソートし、それに応じて、行と列を配置したい場合に便利です。

>>> 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] # reverse order

+0

これはどのように違うのですか?受け入れられた答えから?あなたの答えの各部分はすでに受け入れられた答えに記載されています。 – rayryeng

+0

私が言及したように、これは受け入れられた答えから少しずつ取り上げられますが、受け入れられた答えは、場所のいたるところで話し、不必要な散歩によって物事を複雑にします。私が何をしようとしたか簡単な質問が与えられ、簡単な答えが与えられました。もう余分なものはありません。 –

+0

を参照してください。それでも何も追加しません。私はもちろん努力を感謝します。 – rayryeng

関連する問題