Numpy: np.random.choice返回掩码数组概率的范围索引。

创建于 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,但是当masked array的最后一个元素为true时,它可能返回index = 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])

之前我添加了“ bug”标签,但这是一个主观判断。 numpy中还有其他函数无法正确处理蒙版数组(或者更好,“正确地”处理,因为“正确性”也可以作为判断调用),因此我们不一定认为这是一个错误。 也许这只是未定义行为的示例,对此问题的简短回答是“不要这样做!”。 但是,如果我们可以引发异常而不是返回无意义的结果,那就更好了。

添加一个对掩码数组的显式检查,如果任何一个值实际上被掩码,都会引发一个错误,这很容易,但这感觉像是一个非常具体的临时修复程序。

Generator.choice调度到__array_function__吗? 如果不是,那么可能应该。

如果确实如此,那么我认为我们将其与所有其他“ maskedarray衰减”一起丢弃,因为我们尚未实现__array_function__错误。

之前我添加了“ bug”标签,但这是一个主观判断。 numpy中还有其他函数无法正确处理蒙版数组(或者更好,“正确地”处理,因为“正确性”也可以作为判断调用),因此我们不一定认为这是一个错误。 也许这只是未定义行为的示例,对此问题的简短回答是“不要这样做!”。 但是,如果我们可以引发异常而不是返回无意义的结果,那就更好了。

添加一个对掩码数组的显式检查,如果任何一个值实际上被掩码,都会引发一个错误,这很容易,但这感觉像是一个非常具体的临时修复程序。

我认为,如果处理不正确,则不应允许传递掩码数组(应该引发异常),但大多数情况下都可以正确运行(除了某些情况下,效果很好)。 可能对生产环境造成潜在问题。

Generator没有使用__array_function__ Generator 。 尽管许多强制输入的行为均表现为C连续,但在某些情况下,某些功能可能并不总是如此地有效。

如果添加NPY_ARRAY_ENSUREARRAY则最终会得到一个ndarray已满并且忽略掩码的结果。 很难说这是“正确的”做法。 在@WarrenWeckesser的示例中,最终使用pm=np.array([.1,.2,.3,.4])作为概率。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

keithbriggs picture keithbriggs  ·  3评论

qualiaa picture qualiaa  ·  3评论

manuels picture manuels  ·  3评论

Levstyle picture Levstyle  ·  3评论

inducer picture inducer  ·  3评论