2011-02-18 13 views
7

numpyの検索(地図、またはポイント):私は大きなnumpyの配列持ち

array([[32, 32, 99, 9, 45], # A 
     [99, 45, 9, 45, 32], 
     [45, 45, 99, 99, 32], 
     [ 9, 9, 32, 45, 99]]) 

および特定の順序で一意の値の大っぽい配列:

array([ 99, 32, 45, 9])  # B 

をどのようにすぐに私はでき(AのないPythonの辞書、何のコピー、ないのpythonループが)ので、それはBの値のなインデックスとなりAの値を置き換えません:?

array([[1, 1, 0, 3, 2], 
     [0, 2, 3, 2, 1], 
     [2, 2, 0, 0, 1], 
     [3, 3, 1, 2, 0]]) 

私はこれを私の頭の上から外すことができず、ドキュメントでも見つけられないという理由で、冗談だと感じます。簡単なポイント!ここで

答えて

6

あなたはもともと私が提案し

A = array([[32, 32, 99, 9, 45], # A 
    [99, 45, 9, 45, 32], 
    [45, 45, 99, 99, 32], 
    [ 9, 9, 32, 45, 99]]) 

B = array([ 99, 32, 45, 9]) 

ii = np.argsort(B) 
C = np.digitize(A.reshape(-1,),np.sort(B)) - 1 

を行く:

D = np.choose(C,ii).reshape(A.shape) 

をしかし、私はあなたがより大きなアレイに行ったときには限界があったことに気づきました。その代わり、unutbuの巧妙な回答@からの借入:

D = np.argsort(B)[C].reshape(A.shape) 

または1ライナー私が検討中の配列の大きさに応じて、速いか遅いunutbuのコード@よりであることが判明し

np.argsort(B)[np.digitize(A.reshape(-1,),np.sort(B)) - 1].reshape(A.shape) 

と一意の値の数

+0

を使用して少し速く、所望の結果を計算することができます。 )、しかし記録のために、@ unutbuの解決策は、より良い一般的なパフォーマンスを持つようです。しかし、私が「Aの値を置き換える」と言ったときに欲しかったことを示唆しているかもしれない、「現場で」の解決策でもありませんでした。 ..私はCythonなしでは可能ではないと考えています。両方にありがとう! – Paul

+0

私はまた、B.size << A.sizeの場合を除いて、unutbuの解が一般に速いことも発見しました。最適化を使用して複数のソリューションとティンカーを見ることは常に楽しいことです – JoshAdel

7
import numpy as np 
A=np.array([[32, 32, 99, 9, 45], 
      [99, 45, 9, 45, 32], 
      [45, 45, 99, 99, 32], 
      [ 9, 9, 32, 45, 99]]) 

B=np.array([ 99, 32, 45, 9]) 

cutoffs=np.sort(B) 
print(cutoffs) 
# [ 9 32 45 99] 

index=cutoffs.searchsorted(A) 
print(index) 
# [[1 1 3 0 2] 
# [3 2 0 2 1] 
# [2 2 3 3 1] 
# [0 0 1 2 3]]  

indexAの各要素に関連する配列カットオフへのインデックスを保持します。 np.searchsortedはソートされた配列を期待しているので、Bをソートしなければならなかったことに注意してください。

indexたちは

1-->1 
3-->0 
0-->3 
2-->2 

np.argsortをマップすることを除いて、ほとんど希望答えは、このマッピングを提供してくれます:

だから、
print(np.argsort(B)) 
# [3 1 2 0] 
print(np.argsort(B)[1]) 
# 1 
print(np.argsort(B)[3]) 
# 0 
print(np.argsort(B)[0]) 
# 3 
print(np.argsort(B)[2]) 
# 2 

print(np.argsort(B)[index]) 
# [[1 1 0 3 2] 
# [0 2 3 2 1] 
# [2 2 0 0 1] 
# [3 3 1 2 0]] 

、ワンライナーとして、答えは次のとおりです。

np.argsort(B)[np.sort(B).searchsorted(A)] 

np.sort(B)np.argsort(B)の両方を呼び出すのは、両方の操作がソートになるため、非効率的です。B。任意の1DアレイBため、

np.sort(B) == B[np.argsort(B)] 

そこでこのソリューションは私のユースケース(B.size << A.sizeため適度に速く実行

key=np.argsort(B) 
result=key[B[key].searchsorted(A)] 
関連する問題