2012-01-23 2 views
4

以下の構造の3つのnumpy再配列があります。 最初の列はある位置(整数)で、2番目の列はスコア(浮動小数点数)です。1列の共通の値に基づいて2つ以上の2次元配列から交点を作成する

入力:

a = [[1, 5.41], 
    [2, 5.42], 
    [3, 12.32], 
    dtype=[('position', '<i4'), ('score', '<f4')]) 
    ] 

b = [[3, 8.41], 
    [6, 7.42], 
    [4, 6.32], 
    dtype=[('position', '<i4'), ('score', '<f4')]) 
    ] 

c = [[3, 7.41], 
    [7, 6.42], 
    [1, 5.32], 
    dtype=[('position', '<i4'), ('score', '<f4')]) 
    ] 

すべての3列は、要素の同じ量を含有します。
私はこれら3つの2次元配列を位置列に基づいて1つの配列に結合する効率的な方法を探しています。

次のようになり、上記の例の出力arary:

出力:この位置は、すべての3入力に現れるので、位置3と

output = [[3, 12.32, 8.41, 7.41], 
      dtype=[('position', '<i4'), ('score1', '<f4'),('score2', '<f4'),('score3', '<f4')])] 

行のみが出力配列でありますアレイ。

更新:私の素朴なアプローチは、手順を以下のようになります。

  1. 私の3つの入力配列の最初の列のベクトルを作成します。
  2. これらの3つのベクトルの交点を得るためにintersect1Dを使用します。
  3. 何とか3つの入力配列のベクトルのインデックスを取得します。
  4. 3つの入力配列からフィルタされた行を含む新しい配列を作成します。

アップデート2: 各位置の値は1つ、2つ、または3つのすべての入力アレイとすることができます。私の出力配列では、3つの入力配列すべてに現れる位置値の行だけを入れたいと思っています。

+0

位置の値が異なると、配列の形状が正しくない場合はどうなりますか? – jterrace

+0

わかっていれば分かりません。 Iは、3つの入力配列は常に同じ形状/構造を有することを保証することができる(N、1)と私の場合はいつも3つの入力配列を有します。出力配列は形状(X、4) –

+0

でなければなりません。したがって、配列にはALLが入っていますか、またはNONEに値が入っていますか?つまり、値を含む2/3が得られないでしょうか?また、reprを表示するのではなく、配列を作成するために質問を編集できますか? – jterrace

答えて

3

これは1つのアプローチですが、それは合理的に速いはずです。私はあなたがしたい最初のことは、各ポジションの発生数を数えることだと思います。この関数はそれを処理します:

あなたが3回発生位置のみを取りたいの上に今、関数形式を使用して
def count_positions(positions): 
    positions = np.sort(positions) 
    diff = np.ones(len(positions), 'bool') 
    diff[:-1] = positions[1:] != positions[:-1] 
    count = diff.nonzero()[0] 
    count[1:] = count[1:] - count[:-1] 
    count[0] += 1 
    uniqPositions = positions[diff] 
    return uniqPositions, count 

positions = np.concatenate((a['position'], b['position'], c['position'])) 
uinqPos, count = count_positions(positions) 
uinqPos = uinqPos[count == 3] 

私たちは、私たちはソートABとCのソート、検索を使用することになります:

a.sort(order='position') 
b.sort(order='position') 
c.sort(order='position') 

今、私たちは、ユーザーの検索は、各配列で私たちのuniqPosのそれぞれを検索する場所を見つけるためにソートすることができます

new_array = np.empty((len(uinqPos), 4)) 
new_array[:, 0] = uinqPos 
index = a['position'].searchsorted(uinqPos) 
new_array[:, 1] = a['score'][index] 
index = b['position'].searchsorted(uinqPos) 
new_array[:, 2] = b['score'][index] 
index = c['position'].searchsorted(uinqPos) 
new_array[:, 3] = c['score'][index] 

は、辞書を使用して、よりエレガントな解決策があるかもしれませんが、私は他の誰かにそれを残しておきますので、私が最初にこの1を考えました。

+0

それは動作するコードのおかげで。 –

関連する問題