Как именно numpy.where () выбирает элементы в этом примере? - PullRequest
0 голосов
/ 02 февраля 2019

Из NumPy Документы

>>> np.where([[True, False], [True, True]],
    ...          [[1, 2], [3, 4]],
    ...          [[9, 8], [7, 6]])
array([[1, 8],
       [3, 4]])

Прав ли я, предполагая, что часть [[True, False], [True, True]] является условием, а [[1, 2], [3, 4]] и [[9, 8], [7, 6]] равны x и y соответственно в соответствии спараметры документов.

Тогда как именно функция выбирает элементы в следующих примерах?

Кроме того, почему тип элемента в этих примерах является списком?

>>> np.where([[True, False,True], [False, True]], [[1, 2,56], [3, 4]], [[9, 8,79], [7, 6]])
array([list([1, 2, 56]), list([3, 4])], dtype=object)
>>> np.where([[False, False,True,True], [False, True]], [[1, 2,56,69], [3, 4]], [[9, 8,90,100], [7, 6]])
array([list([1, 2, 56, 69]), list([3, 4])], dtype=object)

Ответы [ 3 ]

0 голосов
/ 02 февраля 2019

np.where(condition,x,y) Он проверяет условие, и если его True возвращает x, иначе он возвращает y

np.where([[True, False], [True, True]], [[1, 2], [3, 4]], [[9, 8], [7, 6]])

Здесь ваше условие равно [[True, False], [True, True]] x = [[1 , 2] , [3 , 4]] y = [[9 , 8] , [7 , 6]]

Первое условиеЗначение true, поэтому возвращается 1 вместо 9

Второе условие - false, поэтому возвращается 8 вместо 2

0 голосов
/ 03 февраля 2019

После прочтения о трансляции , как предложил @hpaulj, я думаю, что знаю, как работает эта функция.Он попытается транслировать 3 массива, затем, если трансляция прошла успешно, он будет использовать значения True и False для выбора элементов из x или y.В примере

>>>np.where([[True, False,True], [False, True]], [[1, 2,56], [3, 4]], [[9, 8,79], [7, 6]])

У нас есть

cnd=np.array([[True, False,True], [False, True]])
x=np.array([[1, 2,56], [3, 4]])
y=np.array([[9, 8,79], [7, 6]])

Теперь

>>>x.shape
Out[7]: (2,)
>>>y.shape
Out[8]: (2,)
>>>cnd.shape
Out[9]: (2,)

Итак, все три - это просто массивы с 2 элементами (списка типов) и условием(cnd). Так что и [True, False,True], и [False, True] будут оцениваться как True. И оба элемента будут выбраны из x.

>>>np.where([[True, False,True], [False, True]], [[1, 2,56], [3, 4]], [[9, 8,79], [7, 6]])
Out[10]: array([list([1, 2, 56]), list([3, 4])], dtype=object)

Я также попробовал это на более сложном примере (2x2x2 вещание), и это все еще объясняет это.

np.where([[[True,False],[True,True]], [[False,False],[True,False]]],
          [[[12,45],[10,50]], [[100,10],[17,81]]],
          [[[90,93],[85,13]], [[12,345], [190,56,34]]])

Где

cnd=np.array([[[True,False],[True,True]], [[False,False],[True,False]]])
x=np.array([[[12,45],[10,50]], [[100,10],[17,81]]])
y=np.array( [[[90,93],[85,13]], [[12,345], [190,56,34]]])

Здесь cnd и x имеют форму (2,2,2), а y имеетформа (2,2).

>>>cnd.shape
Out[14]: (2, 2, 2)
>>>x.shape
Out[15]: (2, 2, 2)
>>>y.shape
Out[16]: (2, 2)

Теперь, как прокомментировал @hpaulj, y будет транслироваться (2,2,2).И это, вероятно, будет выглядеть так:

>>>cnd
Out[6]: 
array([[[ True, False],
        [ True,  True]],
       [[False, False],
        [ True, False]]]) 
>>>x
Out[7]: 
array([[[ 12,  45],
        [ 10,  50]],
       [[100,  10],
        [ 17,  81]]])
>>>np.broadcast_to(y,(2,2,2))
Out[8]: 
array([[[list([90, 93]), list([85, 13])],
        [list([12, 345]), list([190, 56, 34])]],
       [[list([90, 93]), list([85, 13])],
        [list([12, 345]), list([190, 56, 34])]]], dtype=object)

И результат легко может быть предсказан как

>>>np.where([[[True,False],[True,True]], [[False,False],[True,False]]], [[[12,45],[10,50]], [[100,10],[17,81]]],[[[90,93],[85,13]], [[12,345], [190,56,34]]])
Out[9]: 
array([[[12, list([85, 13])],
        [10, 50]],
       [[list([90, 93]), list([85, 13])],
        [17, list([190, 56, 34])]]], dtype=object)
0 голосов
/ 02 февраля 2019

В первом случае каждый член представляет собой массив (2,2) (точнее, список, который может быть преобразован в такой массив).Для каждого True в условии он возвращает соответствующий член в x, [[1 -][3,4]], а для каждого False - член из y [[- 8][- -]]

Во втором случаесписки рваные

In [1]: [[True, False,True], [False, True]]
Out[1]: [[True, False, True], [False, True]]
In [2]: np.array([[True, False,True], [False, True]])
Out[2]: array([list([True, False, True]), list([False, True])], dtype=object)

массив (2,), с 2 списками.И когда приведено как логическое значение, массив из 2 элементов, с обоими True.Только пустой список может выдать значение False.

In [3]: _.astype(bool)
Out[3]: array([ True,  True])

Где затем возвращает только значения x.

Этот второй случай понятен, но патологичен.

moreдетали

Продемонстрируем where более подробно в более простом случае.Тот же массив условий:

In [57]: condition = np.array([[True, False], [True, True]])
In [58]: condition
Out[58]: 
array([[ True, False],
       [ True,  True]])

Версия с одним аргументом, эквивалентная condition.nonzero():

In [59]: np.where(condition)
Out[59]: (array([0, 1, 1]), array([0, 0, 1]))

Некоторым легче представить transpose этого кортежа -3 пары координат, где condition - Истина:

In [60]: np.argwhere(condition)
Out[60]: 
array([[0, 0],
       [1, 0],
       [1, 1]])

Теперь самая простая версия с 3 аргументами и скалярными значениями.

In [61]: np.where(condition, True, False)   # same as condition
Out[61]: 
array([[ True, False],
       [ True,  True]])
In [62]: np.where(condition, 100, 200)
Out[62]: 
array([[100, 200],
       [100, 100]])

Хороший способ визуализации этого действия:с двумя замаскированными присваиваниями.

In [63]: res = np.zeros(condition.shape, int)
In [64]: res[condition] = 100
In [65]: res[~condition] = 200
In [66]: res
Out[66]: 
array([[100, 200],
       [100, 100]])

Другой способ сделать это - инициализировать массив со значениями y, и где ненулевое значение для заполнения значения x.

In [69]: res = np.full(condition.shape, 200)
In [70]: res
Out[70]: 
array([[200, 200],
       [200, 200]])
In [71]: res[np.where(condition)] = 100
In [72]: res
Out[72]: 
array([[100, 200],
       [100, 100]])

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...