2

numpy 配列でタプルを操作しているときに奇妙な動作を発見しました。aarray 内のどのタプルが arrayにも存在するかを示すブール値のテーブルを取得したいと考えていますb。通常、私は、のいずれかを使用しinますin1dtuple(a[1]) == b[1,1]yieldしている間はどれも機能しませんTrue

私は次のように記入abます:

a = numpy.array([(0,0)(1,1)(2,2)], dtype=tuple)

b = numpy.zeros((3,3), dtype=tuple)
for i in range(0,3):
    for j in range(0,3):
        b[i,j] = (i,j)

誰でも私の問題の解決策を教えてもらえますか?なぜこれが期待どおりに機能しないのか教えてください。

(ここでpython2.7とnumpy1.6.2を使用しています。)

4

1 に答える 1

5

これが機能しない理由

短いバージョンでは、numpyのの実装array.__contains__()が壊れているようです。Pythonのin演算子は__contains__()、舞台裏で呼び出します。

a in bと同等の意味b.__contains__(a)

アレイをREPLにロードし、次のことを試してみました。

>>> b[:,0]
array([(0, 0), (1, 0), (2, 0)], dtype=object)
>>> (0,0) in b[:,0] # we expect it to be true
False
>>> (0,0) in list(b[:,0]) # this shouldn't be different from the above but it is
True
>>> 

それを修正する方法

a[x]はタプルであり、2Dマトリックスであるため、リスト内包表記がどのように機能するかわかりませんb[:,:]。もちろん、それらは等しくありません。しかし、私はあなたがinの代わりに使うつもりだったと思います==。私がここで間違っていて、あなたが私が見ていなかった何か違うことを意味したなら、私を訂正してください。

最初のステップはb、2D配列から1D配列に変換することです。これにより、線形にふるいにかけ、リストに変換して、numpyが次のように壊れないarray.__contains()ようにすることができます。

bb = list(b.reshape(b.size))

または、さらに良いことにset、タプルは不変でありin、セット内のチェックはリストのO(n)動作ではなくO(1)であるため、これを作成します。

>>> bb = set(b.reshape(b.size))
>>> print bb
set([(0, 1), (1, 2), (0, 0), (2, 1), (1, 1), (2, 0), (2, 2), (1, 0), (0, 2)])
>>> 

次に、リスト内包表記を使用してブール値のテーブルを導出します

>>> truth_table = [tuple(aa) in bb for aa in a]
>>> print truth_table
[True, True, True]
>>> 

完全なコード:

def contained(a,b):
    bb = set(b.flatten())
    return [tuple(aa) in bb for aa in a]
于 2013-02-24T23:35:32.437 に答える