Numpy где транслируемое состояние - PullRequest
2 голосов
/ 27 марта 2020

Я использовал numpy.where() так много раз, и я всегда задавался вопросом о следующем утверждении в документах :

x, y и условие должно быть транслируемым в какой-то форме.

Я понимаю, почему это необходимо для x и y . Мы хотим собрать результирующий массив из двух, чтобы они могли транслироваться в одну и ту же форму. Однако я не понимаю, почему это так важно и для условия . Это только правило принятия решения. Предположим, у меня есть следующие три фигуры:

condition = (100,)
x         = (100, 5)
y         = (100, 5)
result    = np.where(condition, x, y)

Это приводит к ошибке ValueError, потому что «операнды не могут быть переданы вместе». Насколько я понимаю, это выражение должно работать очень хорошо, потому что я сочиняю свои результаты для x и y, которые можно транслировать.

Можете ли вы помочь мне понять, почему так важно, чтобы условие транслировалось вместе с x а у?

1 Ответ

2 голосов
/ 27 марта 2020

Условие - это в основном логический массив, а не обобщенное c условие. Вы можете думать об этом как о маске поверх окончательной формы вещания x и y.

Если вы думаете об этом таким образом, должно быть ясно, что маска должна иметь ту же форму или быть транслируемой к той же форме, что и конечный результат.

Чтобы проиллюстрировать это, Вот простой пример. Для начала рассмотрим сценарий, в котором мы вручную определили массив масок 3x3 как наш condition, и мы передаем два массива из 3 элементов в виде x и y, сформированных для соответствующей трансляции:

condition = numpy.array([[0, 1, 1],
                         [1, 0, 1],
                         [0, 0, 1]])
ones = numpy.ones(3)
numpy.where(condition, ones[:, None], ones[None, :] + 1)

Результат выглядит следующим образом:

>>> numpy.where(condition, ones[:, None], ones[None, :] + 1)
array([[2., 1., 1.],
       [1., 2., 1.],
       [2., 2., 1.]])

Из-за шага вещания x и y ведут себя так, как если бы они были определены следующим образом:

>>> x
array([[1., 1., 1.],
       [1., 1., 1.],
       [1., 1., 1.]])
>>> y
array([[2., 2., 2.],
       [2., 2., 2.],
       [2., 2., 2.]])
>>> numpy.where(condition, ones[:, None], ones[None, :] + 1)
array([[2., 1., 1.],
       [1., 2., 1.],
       [2., 2., 1.]])

Это фундаментальное поведение where. Тот факт, что вы можете передать условие вроде (x > 5), ничего не меняет в вышеприведенном; (x > 5) становится логическим массивом, и он должен иметь ту же форму, что и выходные данные, иначе он должен быть транслируемым в эту форму. В противном случае поведение where будет некорректным.

(Кстати, я предполагаю, что ваш вопрос не в том, почему фигуры (100,), (100, 5) и (100, 5) aren ' t транслируемый, это, кажется, другой вопрос.)

...