如何解决Pandas:如何根据 Z 分数值突出显示单元格值?
在下面的 df
中,我想:
数据集见下文
import pandas as pd
from scipy import stats
# intialise data of lists
df = {
'col_A':['P0','P1','P2','P4','P5'],'col_B':[1,1,1],'col_C':[1,2,3,5,9],'col_D':[120.05,181.90,10.34,153.10,311.17],'col_E':[110.21,191.12,190.21,12.00,245.09 ],'col_F':[100.22,199.10,191.13,199.99,255.19],'col_G':[140.29,291.07,390.22,245.09,4122.62],}
# Create DataFrame
df = pd.DataFrame(df)
# Print the output.
df
期望:首先标记 col_D
中的所有异常值,然后标记 col_D
和 col_E
(注意:在我下面的图片中,10.34
和 12.00
被随机突出显示)
第一季度
尝试:
#Q1
exclude_cols = ['col_A','col_B','col_C','col_D','col_F','col_G']
include_cols = ['col_E'] # desired column
def flag_outliers(s,exclude_cols):
if s.name in exclude_cols:
print(s.name)
return ''
else:
s=df[(np.abs(stats.zscore(df['col_E'])) > 3)] # not sure of this part of the code
return ['background-color: yellow' if v else '' for v in indexes]
df.style.apply(lambda s: flag_outliers(s,exclude_cols),axis=1,subset=include_cols)
#Q2
exclude_cols = ['col_A','col_G']
include_cols = ['col_D','col_E'] # desired columns
def flag_outliers(s,subset=include_cols)
谢谢!
解决方法
我假设以下含义是为了展示更广泛的用法。
- Q1 代表计算单列
- Q2 代表对汇集在一起的多个列进行计算。
如果 Q2 打算分别在多个列上计算,那么您可以简单地在多个列上循环 Q1 解决方案,这应该是微不足道的,因此我将在此处省略这种情况。
按键
- Q1 非常简单,因为您可以通过列表推导返回值列表。
- Q2 有点复杂,因为 z-score 将应用于 DataFrame 子集(即必须使用
axis=None
)。根据 official docs,当在 DataFrame 上应用样式时,返回的对象也必须是一个与子集具有相同索引和列的 DataFrame。这就是导致重塑和 DataFrame 构建工件的原因。
单列 (Q1)
请注意,出于演示目的,z=3
被降低为 1.5
。
# 想要的列
include_cols = ['col_E']
# additional control
outlier_threshold = 1.5 # 3 won't work!
ddof = 0 # degree of freedom correction. Sample = 1 and population = 0.
def flag_outliers(s: pd.Series):
outlier_mask = np.abs(stats.zscore(s,ddof=ddof)) > outlier_threshold
# replace boolean values with corresponding strings
return ['background-color: yellow' if val else '' for val in outlier_mask]
df.style.apply(flag_outliers,subset=include_cols)
结果
多列合并(Q2,假设)
第二季度
include_cols = ['col_D','col_E'] # desired columns
outlier_threshold = 1.5
ddof = 0
def flag_outliers(s: pd.DataFrame) -> pd.DataFrame:
outlier_mask = np.abs(stats.zscore(s.values.reshape(-1),axis=None,ddof=ddof)) > outlier_threshold
# prepare the array of string to be returned
arr = np.array(['background-color: yellow' if val else '' for val in outlier_mask],dtype=object).reshape(s.shape)
# cast the array into dataframe
return pd.DataFrame(arr,columns=s.columns,index=s.index)
df.style.apply(flag_outliers,subset=include_cols)
结果
,基于这个answer,只需将分数的条件传递给一个存储每个列索引背景颜色的字典。
include_cols = ['col_D','col_E']
def color_outliers_yellow(row,include,color='yellow',z_score = 1):
styles = {col: '' for col in row.index}
if row.name in include:
scores = stats.zscore(list(row))
scores = [(f'background-color: {color}' if score > z_score else '') for score in scores]
return {k:v for k,v in zip(styles.keys(),scores)}
else:
return styles
df.style.apply(lambda x: color_outliers_yellow(x,include=include_cols),axis=0)
结果:
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。