Замаскирован `np.nan` в проблеме` np.ma.array` в jupyter - PullRequest
0 голосов
/ 21 февраля 2020

Запустим в Anaconda Jupyter код Python3 NumPy:

y = np.ma.array(np.matrix([[np.nan, 2.0]]), mask=[0, 1])
m = (y < 0.01)

и у нас будет предупреждение: /.../anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:2: RuntimeWarning: invalid value encountered in less.

Подставляя np.nan с 1.0 et c. --- без предупреждения.

Почему np.nan нельзя замаскировать, а затем сравнить?

Ответы [ 2 ]

1 голос
/ 21 февраля 2020

MA имеет несколько стратегий для реализации методов.

1) оцените метод на y.data и создайте новый ma с y.mask. Он может подавлять любые предупреждения времени выполнения.

2) оценивать метод на y.filled() # со значением заполнения по умолчанию

3) оценивать метод на y.filled(1) # или каком-либо другом безобидном значении

4) оценить метод на y.compressed()

5) оценить метод на y.data[~y.mask]

умножение, например, использовать filled(1), а сложение использует filled(0) .

Похоже, что сравнения сделаны с 1).

Я не изучил код ma подробно, но я не думаю, что он делает 5).

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

  • есть коллекция np.nan... функций, которые отфильтровывают nan перед вычислением

  • есть способы перерасчета Предупреждения времени выполнения

  • ufuncs имеют параметр where, который можно использовать для пропуска некоторых элементов. Используйте его с параметром out для определения пропущенных.

===

Глядя на np.ma.core.py Я вижу такие функции, как ma.less.

In [857]: y = np.ma.array([np.nan, 0.0, 2.0], mask=[1, 0, 0])                                  
In [858]: y >1.0                                                                               
/usr/local/bin/ipython3:1: RuntimeWarning: invalid value encountered in greater
  #!/usr/bin/python3
Out[858]: 
masked_array(data=[--, False, True],
             mask=[ True, False, False],
       fill_value=True)
In [859]: np.ma.greater(y,1.0)                                                                 
Out[859]: 
masked_array(data=[--, False, True],
             mask=[ True, False, False],
       fill_value=True)

Глядя на код, ma.less и т.п. это класс MaskedBinaryOperation, и используйте 1) - оцените по data с

np.seterr(divide='ignore', invalid='ignore')

Маска результата логична комбинация масок аргументов.

https://docs.scipy.org/doc/numpy/reference/maskedarray.generic.html#operations -на маскированных массивах

0 голосов
/ 21 февраля 2020

Чтобы упростить задачу, давайте предположим:

y = np.ma.array([np.nan, 0.0, 2.0], mask=[1, 0, 0])
m = (y > 1.0)
print(y, y.shape) ; print(y[m], y[m].shape, m.shape)

и получим:

[-- 0.0 2.0] (3,)
[2.0] (1,) (3,)

с предупреждением RuntimeWarning: /.../anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:2: RuntimeWarning: invalid value encountered in greater.

Изменение :

...
m = (y != 2.0)
...

Мы получаем:

[-- 0.0 2.0] (3,)
[-- 0.0] (2,) (3,)

, поэтому у нас есть маскированный элемент и результат без RuntimeWarning.

Изменение сейчас:

...
m = y.mask.copy() ; y[np.isnan(y)] = 9.0 ; y.mask = m ; m = (y > 1.0)
...

Мы получаем (без RuntimeWorning):

[-- 0.0 2.0] (3,)
[-- 2.0] (2,) (3,)

Этот обходной путь, однако, странный (путем установки произвольного значения вместо np.nan и сохранения маски). Сравнение чего-то с masked должно быть всегда masked, не так ли?

...