Подтвердить что ты не робот

Среднее значение, nanmean и предупреждение: среднее значение пустого среза

Скажем, я построю два массива numpy:

a = np.array([np.NaN, np.NaN])
b = np.array([np.NaN, np.NaN, 3])

Теперь я обнаружил, что np.mean возвращает nan для a и b:

>>> np.mean(a)
nan
>>> np.mean(b)
nan

Так как numpy 1.8 (выпущено 20 апреля 2016 года), мы получили благословение nanmean, которое игнорирует значения nan:

>>> np.nanmean(b)
3.0

Однако, когда массив не имеет значений , но nan, он вызывает предупреждение:

>>> np.nanmean(a)
nan
C:\python-3.4.3\lib\site-packages\numpy\lib\nanfunctions.py:598: RuntimeWarning: Mean of empty slice
  warnings.warn("Mean of empty slice", RuntimeWarning)

Я не люблю подавлять предупреждения; есть ли более эффективная функция, которую я могу использовать для получения поведения nanmean без этого предупреждения?

4b9b3361

Ответ 1

Я действительно не вижу никакой веской причины не просто подавлять предупреждение.

Самым безопасным способом было бы использовать контекстный менеджер warnings.catch_warnings, чтобы подавить предупреждение только там, где вы его ожидаете - таким образом, вы не пропустит никаких дополнительных RuntimeWarnings, которые могут неожиданно возникнуть в какой-либо другой части вашего кода:

import numpy as np
import warnings

x = np.ones((1000, 1000)) * np.nan

# I expect to see RuntimeWarnings in this block
with warnings.catch_warnings():
    warnings.simplefilter("ignore", category=RuntimeWarning)
    foo = np.nanmean(x, axis=1)

@dawg также будет работать, но в конечном итоге любые дополнительные шаги, которые вы должны предпринять, чтобы избежать вычисления np.nanmean в массиве всех NaN, будут нести дополнительные дополнительные накладные расходы, которые можно было бы избежать, просто подавив предупреждение, Также ваше намерение будет гораздо более четко отражено в коде.

Ответ 2

Значение A NaN определяется как не равное самому себе:

>>> float('nan') == float('nan')
False
>>> np.NaN == np.NaN
False

Вы можете использовать условное выражение Python и свойство нанка, никогда не равное себе, чтобы получить такое поведение:

>>> a = np.array([np.NaN, np.NaN])
>>> b = np.array([np.NaN, np.NaN, 3])
>>> np.NaN if np.all(a!=a) else np.nanmean(a)
nan
>>> np.NaN if np.all(b!=b) else np.nanmean(b)
3.0

Вы также можете сделать:

import warnings
import numpy as np

a = np.array([np.NaN, np.NaN])
b = np.array([np.NaN, np.NaN, 3])

with warnings.catch_warnings():
    warnings.filterwarnings('error')
    try:
        x=np.nanmean(a)
    except RuntimeWarning:
        x=np.NaN    
print x