Выделите выбросы с помощью zscore в панд

#python #pandas

Вопрос:

Я хочу, чтобы значения стиля были выбросами, основанными на их оценках z.
Примеры данных:

 import numpy as np import pandas as pd array=[[750.0, 1.1e-09, 'daljk', 6.0],  [890.0, 1e-09, 'djfh', 8.0],  [1720.0, 1e-09, 'dkhf', 4.0],  [999.0, 1e-09, 'dkafh', 10.0],  [890.0, 1e-09, 'dkajfh', 0.0005],  [909.0, 1e-09, 'jkdafh', 6.0],  [1002.0, 1e-09, 'dlfakh', np.nan],  [990.0, 1e-09, 'ldkj', 3.0],  [0.0001, 1e-09, 'dlkfj', 10.0]] df = pd.DataFrame(array, columns = ['A','B','C','D']) df  

дает

  Out[4]:  A B C D 0 750.0000 1.100000e-09 daljk 6.0000 1 890.0000 1.000000e-09 djfh 8.0000 2 1720.0000 1.000000e-09 dkhf 4.0000 3 999.0000 1.000000e-09 dkafh 10.0000 4 890.0000 1.000000e-09 dkajfh 0.0005 5 909.0000 1.000000e-09 jkdafh 6.0000 6 1002.0000 1.000000e-09 dlfakh NaN 7 990.0000 1.000000e-09 ldkj 3.0000 8 0.0001 1.000000e-09 dlkfj 10.0000  

Я написал функцию ниже на основе некоторого кода, который я получил от другого, поэтому ответьте, чтобы выделить z баллов БОЛЬШЕ 1,5:

 def highlight_outliers(x):  color ='orange'  #extract numeric columns  c=x.select_dtypes([np.number]).columns  #create df of numeric cols  df2=pd.DataFrame(x,columns=c)  #calculate zscores  df2=df2.apply(stats.zscore, nan_policy='omit').abs()  #boolean mask of values greater than threshold value  mask=(df2[c].apply(pd.to_numeric, errors='coerce').fillna(np.Inf).replace(0, np.Inf).valueslt;1.5)  #create blank df of numeric cols  df1=pd.DataFrame('',index=x.index, columns=c)  #style locations which exceed threshold (fill orange) based on mask  df1=(df1.where(mask, 'background-color:{}'.format(color)).reindex(columns=x.columns, fill_value=''))  return df1 df_styled=df.style.apply(highlight_outliers, axis=None) df_styled  

Что дает:

выходное изображение

Это примерно правильно. Тем не менее, мой вопрос таков: я не хочу выделять значения NaN и думал, что .fillna(np.Inf) деталь должна исправить это, но, похоже, этого не происходит. Как я могу избежать выделения значений NaN?

Ответ №1:

Здесь есть лишь небольшое заблуждение. Так where как заменяет все False значения, вы соответственно фильтруете по lt;1.5 . Однако Inf lt; 1.5 = False , следовательно , это будет подчеркнуто позже. Чтобы «исключить» его, вам скорее нужно вставить -Inf .

Из документации:

Если значение cond равно True, сохраните исходное значение. Где False, замените соответствующим значением из другого.

 def highlight_outliers(x):  color ='orange'  #extract numeric columns  c=x.select_dtypes([np.number]).columns  #create df of numeric cols  df2=pd.DataFrame(x,columns=c)  #calculate zscores  df2=df2.apply(stats.zscore, nan_policy='omit').abs()  #boolean mask of values greater than threshold value  mask=(df2[c].apply(pd.to_numeric, errors='coerce').fillna(-np.Inf).replace(0, -np.Inf).valueslt;1.5)#  #create blank df of numeric cols  df1=pd.DataFrame('',index=x.index, columns=c)  #style locations which exceed threshold (fill orange) based on mask  df1=(df1.where(mask, 'background-color:{}'.format(color)).reindex(columns=x.columns, fill_value=''))  return df1 df_styled=df.style.apply(highlight_outliers, axis=None) df_styled  

введите описание изображения здесь

Комментарии:

1. Спасибо, это здорово, что я не учел отрицательную бесконечность. Вы также прояснили еще один мой вопрос о том, почему я должен использовать «меньше» вместо «больше» в логике zscore, поскольку » где » заменяет False. Спасибо