#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. Спасибо