2016-04-10 8 views
4

配列dataresultの2つのセットがあります。 resultには同じ要素がdataに含まれていますが、追加の列があり、並べ替えられていません。 result配列をdataの行と同じ順序に並べ替えると同時に、並べ替えを実行するときに行の残りの部分と最後の列に関連付けられた値が表示されます。私は、ソートがそれぞれを扱いたいのに対し、私は、その後、resultにそれを適用するソート順にdataを反転させるためにargsortをやってみましたが、それぞれの要素に基づいて、配列の順番を並べ替えることargsort思わまし別の配列のデータに基づいて配列を並べ替える

data = np.array([[0,1,0,0],[1,0,0,0],[0,1,1,0],[0,1,0,1]]) 
result = np.array([[0,1,1,0,1],[1,0,0,0,0],[0,1,0,0,1],[0,1,0,1,0]]) 

# this is what the final sorted array should look like: 
''' 
array([[0, 1, 0, 0, 1], 
     [1, 0, 0, 0, 0], 
     [0, 1, 1, 0, 1], 
     [0, 1, 0, 1, 0]]) 
''' 

全体としてdata[:,4]の行。

ind = np.argsort(data) 
indind =np.argsort(ind) 
ind 
array([[0, 2, 3, 1], 
    [1, 2, 3, 0], 
    [0, 3, 1, 2], 
    [0, 2, 1, 3]]) 

このような種類の並べ替えを行うにはどうすればよいですか?

+0

は、常に最後の列に配置される余分な列ですか? – Deusdeorum

答えて

0

あなたがしていることを明確にしようとするだけです。インデックスリスト[2,1,0,3]で、私はこのようにresultの行を並べ替えることができます。

In [37]: result[[2,1,0,3],:] 
Out[37]: 
array([[0, 1, 0, 0, 1], 
     [1, 0, 0, 0, 0], 
     [0, 1, 1, 0, 1], 
     [0, 1, 0, 1, 0]]) 

In [38]: result[[2,1,0,3],:4]==data 
Out[38]: 
array([[ True, True, True, True], 
     [ True, True, True, True], 
     [ True, True, True, True], 
     [ True, True, True, True]], dtype=bool) 

私はargsortまたはsortこのインデックス順を思い付く助けるために起こっているか表示されません。

np.lexsortで、私は同じ両方の配列の行を注文することができます:私は転置を使用するために必要な試行錯誤によって発見

In [54]: data[np.lexsort(data.T),:] 
Out[54]: 
array([[1, 0, 0, 0], 
     [0, 1, 0, 0], 
     [0, 1, 1, 0], 
     [0, 1, 0, 1]]) 

In [55]: result[np.lexsort(result[:,:-1].T),:] 
Out[55]: 
array([[1, 0, 0, 0, 0], 
     [0, 1, 0, 0, 1], 
     [0, 1, 1, 0, 1], 
     [0, 1, 0, 1, 0]]) 

。その理由を理解するために、lexsortのドキュメントを確認する必要があります。

もう少し試行錯誤を生成します。

In [66]: i=np.lexsort(data.T) 
In [67]: j=np.lexsort(result[:,:-1].T) 
In [68]: j[i] 
Out[68]: array([2, 1, 0, 3], dtype=int64) 

In [69]: result[j[i],:] 
Out[69]: 
array([[0, 1, 0, 0, 1], 
     [1, 0, 0, 0, 0], 
     [0, 1, 1, 0, 1], 
     [0, 1, 0, 1, 0]]) 

これは暫定的なソリューションです。他のサンプルでもテストする必要があります。そして、説明する必要があります。

0

アプローチ#1

ここインデキシングタプルとして各行を考慮し、それらの線形インデックス当量に相当するdataresult間マッチング指標を求める手法です。これらのインデックスは新しい行の順序を表し、結果に索引付けされると望ましい出力が得られます。実装は次のようになります -

# Slice out from result everything except the last column  
r = result[:,:-1]  

# Get linear indices equivalent of each row from r and data 
ID1 = np.ravel_multi_index(r.T,r.max(0)+1) 
ID2 = np.ravel_multi_index(data.T,r.max(0)+1) 

# Search for ID2 in ID1 and use those indices index into result 
out = result[np.where(ID1[:,None] == ID2)[1]] 

アプローチ#2

dataからすべての行がresultであることが保証されている場合は、そのようなだけargsortに基づいて別のアプローチを、使用することができます -

# Slice out from result everything except the last column  
r = result[:,:-1]  

# Get linear indices equivalent of each row from r and data 
ID1 = np.ravel_multi_index(r.T,r.max(0)+1) 
ID2 = np.ravel_multi_index(data.T,r.max(0)+1) 

sortidx_ID1 = ID1.argsort() 
sortidx_ID2 = ID2.argsort() 
out = result[sortidx_ID1[sortidx_ID2]] 

もう少し一般的なケースのためのサンプル実行 -

In [37]: data 
Out[37]: 
array([[ 3, 2, 1, 5], 
     [ 4, 9, 2, 4], 
     [ 7, 3, 9, 11], 
     [ 5, 9, 4, 4]]) 

In [38]: result 
Out[38]: 
array([[ 7, 3, 9, 11, 55], 
     [ 4, 9, 2, 4, 8], 
     [ 3, 2, 1, 5, 7], 
     [ 5, 9, 4, 4, 88]]) 

In [39]: r = result[:,:-1] 
    ...: ID1 = np.ravel_multi_index(r.T,r.max(0)+1) 
    ...: ID2 = np.ravel_multi_index(data.T,r.max(0)+1) 
    ...: 

In [40]: result[np.where(ID1[:,None] == ID2)[1]] # Approach 1 
Out[40]: 
array([[ 3, 2, 1, 5, 7], 
     [ 4, 9, 2, 4, 8], 
     [ 7, 3, 9, 11, 55], 
     [ 5, 9, 4, 4, 88]]) 

In [41]: sortidx_ID1 = ID1.argsort() # Approach 2 
    ...: sortidx_ID2 = ID2.argsort() 
    ...: 

In [42]: result[sortidx_ID1[sortidx_ID2]] 
Out[42]: 
array([[ 3, 2, 1, 5, 7], 
     [ 4, 9, 2, 4, 8], 
     [ 7, 3, 9, 11, 55], 
     [ 5, 9, 4, 4, 88]]) 
+0

この回答は、上記の例のような小さなデータセットで機能しますが、大きなサンプル(5172x32データセット)を使用すると、「ValueError:ravel_multi_indexに渡されるディメンションが多すぎます」というエラーが表示されます。私はこれをどのように解決すべきですか? – ROBOTPWNS

+0

@ ROBOTPWNSこれらのID1とID2を計算して、それがうまくいくかどうかを確認してください: 'ID1 = r.dot(r.max(0)+1); ID2 = data.dot(r.max(0)+1) '? – Divakar

+0

@ROBOTPWNSだから、それはあなたのために働いたのですか? – Divakar

0

(免責事項:私はその作者だが)numpy_indexedパッケージ効率的かつエレガントに問題のこれらの種類を解決するために使用することができます。

import numpy_indexed as npi 
result[npi.indices(result[:, :-1], data)] 

npi.indicesは、本質的にlist.indexのベクトル化と同等です。したがって、データ内の各要素(行)に対して、同じ行がresultの最後の列を引いた位置になります。

この解決策は、任意の数の列に対して機能し、完全にベクトル化されていることに注意してください(つまり、どこにもPythonループはありません)。

関連する問題