Numpy: np.random.choice возвращает индекс вне диапазона для замаскированного массива.

Созданный на 15 авг. 2020  ·  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, но когда последний элемент замаскированного массива истинен, он может вернуть index = 4

00 - Bug numpy.ma numpy.random

Все 6 Комментарий

Проблема также возникает в Generator.choice в разрабатываемой версии numpy:

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 . В то время как многие заставляют входные данные вести себя непрерывно C, вероятно, некоторые функции не всегда вызывают это достаточно строго.

Если вы добавите NPY_ARRAY_ENSUREARRAY вы получите заполненный ndarray, игнорирующий маску. Трудно сказать, что это «правильно». В примере @WarrenWeckesser в качестве вероятностей используется pm=np.array([.1,.2,.3,.4]) .

Была ли эта страница полезной?
0 / 5 - 0 рейтинги