Среднее значение, 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
без этого предупреждения?
Ответы
Ответ 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