4

同様の質問が SO で既に尋ねられていますが、より具体的な制約があり、その回答は私の質問には当てはまりません。

一般的に言えば、任意のnumpy配列が別の配列のサブセットであるかどうかを判断する最もpythonicな方法は何ですか? より具体的には、おおよそ 20000x3 の配列があり、セット内に完全に含まれる 1x3 要素のインデックスを知る必要があります。より一般的には、次のように書くより Pythonic な方法はありますか?

master = [12, 155, 179, 234, 670, 981, 1054, 1209, 1526, 1667, 1853]  # some indices of interest
triangles = np.random.randint(2000, size=(20000, 3))  # some data

for i, x in enumerate(triangles):
    if x[0] in master and x[1] in master and x[2] in master:
        print i

私の使用例では、len(master) << 20000 であると安全に想定できます。

4

5 に答える 5

4

リスト内包表記で配列を反復処理することで、これを簡単に行うことができます。おもちゃの例は次のとおりです。

import numpy as np
x = np.arange(30).reshape(10,3)
searchKey = [4,5,8]
x[[0,3,7],:] = searchKey
x

与える

 array([[ 4,  5,  8],
        [ 3,  4,  5],
        [ 6,  7,  8],
        [ 4,  5,  8],
        [12, 13, 14],
        [15, 16, 17],
        [18, 19, 20],
        [ 4,  5,  8],
        [24, 25, 26],
        [27, 28, 29]])

要素を反復処理します。

ismember = [row==searchKey for row in x.tolist()]

結果は

[True, False, False, True, False, False, False, True, False, False]

質問のように、サブセットになるように変更できます。

searchKey = [2,4,10,5,8,9]  # Add more elements for testing
setSearchKey = set(searchKey)
ismember = [setSearchKey.issuperset(row) for row in x.tolist()]

インデックスが必要な場合は、使用します

np.where(ismember)[0]

それは与えます

array([0, 3, 7])
于 2013-05-14T16:59:41.430 に答える
3

試すことができる2つのアプローチを次に示します。

1、セットを使う。セットは Python 辞書と同じように実装され、一定時間のルックアップがあります。これは、マスターからセットを作成するだけで、既に持っているコードによく似ています。

master = [12,155,179,234,670,981,1054,1209,1526,1667,1853]
master_set = set(master)
triangles = np.random.randint(2000,size=(20000,3)) #some data
for i, x in enumerate(triangles):
  if master_set.issuperset(x):
    print i

2、ソートされた検索を使用します。ハッシュ可能な型を使用する必要がなく、numpy のビルトインを使用するため、これは便利です。searchsortedmaster のサイズが log(N) であり、三角形のサイズが O(N) であるため、配列のサイズなどによってはかなり高速になる可能性があります。

master = [12,155,179,234,670,981,1054,1209,1526,1667,1853]
master = np.asarray(master)
triangles = np.random.randint(2000,size=(20000,3)) #some data
idx = master.searchsorted(triangles)
idx.clip(max=len(master) - 1, out=idx)
print np.where(np.all(triangles == master[idx], axis=1))

この 2 番目のケースでは、マスターがソートされていることを前提としていsearchsortedます。

于 2013-05-14T17:13:15.657 に答える