Numpy: np.random.choiceは、マスクされた配列probの範囲外のインデックスを返します。

作成日 2020年08月15日  ·  6コメント  ·  ソース: numpy/numpy

import numpy as np

a = np.array([0.1, 0.2, 0.4, 0.3])
masked_a = np.ma.masked_array(a, [0, 0, 1, 1])
counter = np.zeros(len(a) + 1)
while True:
    action = np.random.choice(len(a), p=masked_a)
    counter[action] += 1
    print(counter / counter.sum())

# [0.09931198 0.20076697 0.         0.         0.69992105]

3を超えるインデックスを返すことはできませんが、マスクされた配列の最後の要素がtrueの場合、インデックス= 4を返す可能性があります。

00 - Bug numpy.ma numpy.random

全てのコメント6件

この問題は、numpyの開発バージョンのGenerator.choiceでも発生します。

In [1]: import numpy as np

In [2]: np.__version__ 
Out[2]: '1.20.0.dev0+986e533'

In [3]: rng = np.random.default_rng()

In [4]: pm = np.ma.masked_array([0.1, 0.2, 0.4, 0.3], mask=[0, 0, 1, 1])

In [5]: rng.choice(4, p=pm, size=12)
Out[5]: array([4, 4, 4, 0, 4, 1, 4, 0, 0, 4, 4, 4])

以前、「バグ」ラベルを追加しましたが、それは主観的な判断です。 numpyには、マスクされた配列を正しく処理しない(または、「正確さ」も判断の呼び出しになる可能性があるため、「正しく」)他の関数がありますが、必ずしもバグとは見なされません。 おそらく、これは未定義の動作の単なる例であり、この問題の簡単な答えは「それをしないでください!」です。 ただし、無意味な結果を返す代わりに例外を発生させることができれば、より良いでしょう。

マスクされた配列の明示的なチェックを追加し、値のいずれかが実際にマスクされている場合はエラーを発生させるのは簡単ですが、それは非常に具体的なアドホックな修正のように感じます。

Generator.choiceに派遣__array_function__ ? そうでない場合は、おそらくそうすべきです。

もしそうなら、私たちはこれを他のすべての「 __array_function__まだ実装していないのでマスクされた配列の崩壊」バグと一緒に投入すると思います。

以前、「バグ」ラベルを追加しましたが、それは主観的な判断です。 numpyには、マスクされた配列を正しく処理しない(または、「正確さ」も判断の呼び出しになる可能性があるため、「正しく」)他の関数がありますが、必ずしもバグとは見なされません。 おそらく、これは未定義の動作の単なる例であり、この問題の簡単な答えは「それをしないでください!」です。 ただし、無意味な結果を返す代わりに例外を発生させることができれば、より良いでしょう。

マスクされた配列の明示的なチェックを追加し、値のいずれかが実際にマスクされている場合はエラーを発生させるのは簡単ですが、それは非常に具体的なアドホックな修正のように感じます。

正しく処理されない場合は、マスクされた配列を渡すことはできませんが(例外が発生するはずです)、ほとんど正しく機能します(場合によってはうまく機能します)。 実稼働環境に潜在的な問題を引き起こす可能性があります。

__array_function__ではGenerator __array_function__は使用されません。 多くの強制入力がCで連続して適切に動作するように強制しますが、一部の関数が必ずしもこれを十分に宗教的に強制するとは限らない場合があります。

NPY_ARRAY_ENSUREARRAYを追加すると、ndarrayがいっぱいになり、マスクが無視されます。 これが「正しい」とは言い難い。 @WarrenWeckesserの例では、これは確率としてpm=np.array([.1,.2,.3,.4])を使用することになります。

このページは役に立ちましたか?
0 / 5 - 0 評価