Python 突出显示基于多个条件的值
我想对等于或超过指导值的值(单元格)进行着色处理(当前在字典中,键(化学符号):值(指导限值)。我希望它能够处理多组指导原则,并根据超出的最高值指导原则对单元格进行着色。下表显示了所需的输出,指导原则指定了颜色,每个指导原则的超出值指定了相同的颜色 这显示了三种不同指南(ANZECC、WHO和美国环境保护局)对铜、镉、SO4和锌的限值。结果如下(现场1-3),并根据其突出显示(如有)它们超过了指导原则。因此,对于第一个参数,Cu,场地2仅超过美国EPA值,因此为黄色阴影。场地1所有指导原则中最高的是WHO值,因此为蓝色阴影。场地3也超过了所有指导原则,最大值为WHO,因此为蓝色阴影。场地1的Cd超过美国EPA和ANZECC(两者相同)同样是绿色阴影(但可能是耶洛斯阴影,因为美国环境保护局的限制是相同的)。场地2没有超过任何指导方针,因此没有阴影。场地3超过所有指导方针,Cd的最高值是WHO,蓝色阴影也是。以此类推 我可以使用下面的代码根据一条准则对超标进行着色Python 突出显示基于多个条件的值,python,pandas,styles,Python,Pandas,Styles,我想对等于或超过指导值的值(单元格)进行着色处理(当前在字典中,键(化学符号):值(指导限值)。我希望它能够处理多组指导原则,并根据超出的最高值指导原则对单元格进行着色。下表显示了所需的输出,指导原则指定了颜色,每个指导原则的超出值指定了相同的颜色 这显示了三种不同指南(ANZECC、WHO和美国环境保护局)对铜、镉、SO4和锌的限值。结果如下(现场1-3),并根据其突出显示(如有)它们超过了指导原则。因此,对于第一个参数,Cu,场地2仅超过美国EPA值,因此为黄色阴影。场地1所有指导原则中最
#示例数据帧
df=pd.DataFrame({'Cu':[0.004,0.0017,0.1],'Cd':[0.001','0.0005',1],'SO4':[700,450,1500],'Zn':[0.15','0.1','0.25'],}))
cols=df.columns
给予
给出:
Out[3]:
镉铜铅硫酸盐锌
ANZECC_FW 0.0002 0.0014 0.0034 1000.0 0 0.008
澳新银行股票0.0100.4000 NaN 1000.0 20.000
CEPA_FW 0.0100 1.0000 0.0050 1000.05.000
然后对指南进行排序并指定颜色,包括:
fill_color={'ANZECC_FW':'blue',
"安排":"绿色",,
“ANZECC_股票”:“黄色”}
对于df.columns中的i:
col=df[i]
col=col.sort_值(升序=真)
#打印列,i,列idxmax()
#打印i
#打印颜色
计数=0
对于col中的val:
如果val>0:
打印i、val、列索引[计数],填充颜色[列索引[计数]]
计数+=1
其他:
持续
给出:
Cd 0.0002 ANZECC_FW蓝色
Cd 0.01 ANZECC_库存黄色
Cd 0.01 CEPA_FW绿色
铜0.0014 ANZECC_FW蓝色
Cu 0.4 ANZECC_库存黄色
Cu 1.0 CEPA_FW绿色
Pb 0.0034 ANZECC_FW蓝色
铅0.005 CEPA_FW绿色
硫酸盐1000.0 ANZECC_FW蓝色
硫酸盐1000.0 ANZECC_库存黄色
硫酸盐1000.0 CEPA_FW绿色
锌0.008 ANZECC_FW蓝
Zn 5.0 CEPA_FW绿色
锌20.0 ANZECC_库存黄色
所以我有了所有的信息,我只需要循环这些信息,以便数据中的每一列(如果单元格值>=列表值,指定填充颜色)都能正常工作,但我一直在思考如何应用这些信息。看起来这就是你可以做到的: 编辑:
import pandas as pd, numpy as np
data=pd.DataFrame(({'Cd': [0.001,0.0005,1],'Cu':[0.004, 0.0017, 0.1], 'SO4': [700,450,1500],'Zn': [0.15,0.1,0.25],}))
guidelines = {'WHO' : {'Cd' :0.002 ,'Cu' :0.003 ,'SO4':np.NaN,'Zn' :0.1},
'ANZECC' : {'Cd' :0.001 ,'Cu' :0.002 ,'SO4':1000.0,'Zn' :0.2},
'US_EPA' : {'Cd' :0.001 ,'Cu' :0.0015 ,'SO4':500.0,'Zn' :0.01}
}
guidelines = pd.DataFrame(guidelines).T
fill_color = {'WHO':'teal','ANZECC': 'red','US_EPA' :'yellow'}
def highlight(x):
if x.name in guidelines.columns:
style = []
guide = guidelines[x.name]
for i in x:
condition = (guide<=i)
_guide = guide[condition]
try:
match = _guide.index[np.argmax(np.array(_guide))]
color = fill_color[match]
style += [f"background-color: {color}"]
except:
style += ['']
return style
else:
return ['']*len(x)
data.style.apply(highlight)
将熊猫作为pd导入,numpy作为np导入
data=pd.DataFrame({'Cd':[0.001,0.0005,1],'Cu':[0.004,0.0017,0.1],'SO4':[7004501500],'Zn':[0.15,0.1,0.25],}))
指南={'WHO':{'Cd':0.002,'Cu':0.003,'SO4':np.NaN,'Zn':0.1},
'ANZECC':{'Cd':0.001,'Cu':0.002,'SO4':1000.0,'Zn':0.2},
‘美国环保署’:{'Cd':0.001,'Cu':0.0015,'SO4':500.0,'Zn':0.01}
}
指南=pd.DataFrame(指南).T
填充颜色={'WHO':'teal','ANZECC':'red','US_EPA':'yellow'}
def突出显示(x):
如果guidelines.columns中的x.name:
样式=[]
指南=指南[x.name]
对于x中的i:
条件=(指南首先,您的问题中有几个问题:
您的数据不一致:为生成df
而提供的代码包含一些混合了浮点数的字符串。如果您的数据中确实存在这种情况,那么您应该做的第一件事是将all转换为float:
df=df.apply(pd.to_数值)
您的指南在整个帖子中都会发生变化。例如:
你从指导方针开始
WHO= {'Cd' :0.002 ,'Cu' :0.003 ,'SO4':"NaN,'Zn' :0.1} # string `NaN` again?
ANZECC= {'Cd' :0.001 ,'Cu' :0.002 ,'SO4':1000.0,'Zn' :0.2}
US_EPA= {'Cd' :0.001 ,'Cu' :0.0015 ,'SO4':500.0,'Zn' :0.01}
然后,稍后您将构建您的指南
数据框架,您一定错误地将其命名为df
,以及:
# no string `NaN`
# Sulphate or SO4
# different standard names
guidelines={"CEPA_FW": {'Sulphate':1000,'Cd' :0.01 ,'Cu' :1.0 ,'Pb' :0.005 ,'Zn' :5.0},
"ANZECC_Stock":{'Sulphate':1000,'Cd' :0.01,'Cu' :0.4, 'Zn' :20},
"ANZECC_FW": {'Sulphate':1000,'Cd' :0.0002 ,'Cu' :0.0014 ,'Pb' :0.0034 ,'Zn' :0.008}}
这与前者完全不同
也就是说,让我们根据您的图片建立一个新的指南
和填充颜色
:
guidelines = {'WHO' : {'Cd' :0.002 ,'Cu' :0.003 ,'SO4':np.NaN,'Zn' :0.1},
'ANZECC' : {'Cd' :0.001 ,'Cu' :0.002 ,'SO4':1000.0,'Zn' :0.2},
'US_EPA' : {'Cd' :0.001 ,'Cu' :0.0015 ,'SO4':500.0,'Zn' :0.01}
}
guidelines = pd.DataFrame(guidelines).T
fill_color = {'WHO':'teal',
'US_EPA' :'yellow',
'ANZECC': 'green'}
下面是函数:
def hightlight(col):
name = col.name
# extract the threshold and sort decreasingly
thresh = guidelines[name].sort_values(ascending=False)
# compare each value in column to each threshold
compare = np.greater_equal.outer(col.values, thresh.values)
# if any threshold is exceeded
exceed_thresh = compare.any(1)
# and where it is exceeded
exceed_idx = np.argmax(compare, axis=1)
# extract the standards that has is passed
standards = np.where(exceed_thresh, thresh.index[exceed_idx], '')
# format strings
return [f'background-color:{fill_color[s]}' if s else '' for s in standards ]
df.style.apply(hightlight)
输出:
限制的格式是什么?它是另一个数据框?或字典列表?是否可以像图片数据一样使用此格式编辑问题?@jezrael是否更好?是的,限制是字典。抱歉,很忙,但正在工作。没有相同值的首选项,可以作为指导原则。谢谢,这将创建一个新字典“大于条件”并将每一列与此进行比较,但每一列都有一个由“指南”字典定义的指南。不需要“大于条件”库。您的答案也对指南进行了着色,而不是对数据进行着色(问题中的第一个代码框)。如果引用了正确的词典,您的方法可能会起作用。是的,我想我错误地将指导原则假定为您的数据,因此,我添加了另一个dict
,以演示如何添加条件。让我在代码中添加df,并使用指导原则进行着色!谢谢,您能检查一下这一点吗,我在运行y时没有得到样式化的输出我们的代码。啊哈!您是否收到np.argmax
(colab上没有显示)的错误?现在,已修复。谢谢。我确实指定了数据可能包含与赏金相关的注释中的NaN或空格。感谢您指出不一致之处,我将修复。您的代码返回错误:NameError:(“名称‘c’未定义)…很抱歉,错过了重构,c
应该在return
行中替换为s
。修复了。如果输入数据的列不在指南中,这会很简单吗?是的,如果名称不在指南中,只需选中。列:return[']*len(col)
对吗
def hightlight(col):
name = col.name
# extract the threshold and sort decreasingly
thresh = guidelines[name].sort_values(ascending=False)
# compare each value in column to each threshold
compare = np.greater_equal.outer(col.values, thresh.values)
# if any threshold is exceeded
exceed_thresh = compare.any(1)
# and where it is exceeded
exceed_idx = np.argmax(compare, axis=1)
# extract the standards that has is passed
standards = np.where(exceed_thresh, thresh.index[exceed_idx], '')
# format strings
return [f'background-color:{fill_color[s]}' if s else '' for s in standards ]
df.style.apply(hightlight)