我要遮盖等于或超过准则值(当前在词典中,键(化学符号):值(准则极限))的值(单元格),我希望它能够处理多组参考线,并根据被超过的最高值的参考线对单元格进行着色。下表显示了所需的输出,并为参考线分配了颜色,每条参考线的超出部分分配了相同的颜色。
这显示了针对铜,镉,二氧化硫和锌的三种不同指南(ANZECC,WHO和美国EPA)的限值。结果在下面(站点1 -3)下方,并根据超出的范围(如果有)进行突出显示。因此,对于第一个参数Cu,位置2仅超过US EPA值,因此阴影为黄色。站点1所有准则中,最高的准则是WHO值,因此阴影为蓝色。站点3也超出了所有准则,最大值是WHO,因此阴影也为蓝色。站点1的Cd超过了US EPA和ANZECC(相同),因此被涂成绿色(但由于US EPA限制相同,本来可以被涂成黄色)。站点2不超出任何准则,因此不要遮挡。站点3超出了所有指南,镉的最高含量是世界卫生组织,因此阴影为蓝色。等等。
我可以使用以下代码针对一项准则遮盖超出部分,
#example dataframe
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[7]:
Cd Cu SO4 Zn
0 0.001 0.0040 700 0.15
1 0.0005 0.0017 450 0.1
2 1 0.1000 1500 0.25
#guideline values
WHO= {'Cd' :0.002 ,'Cu' :0.003 ,'SO4':"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}
#highlight the relevant cells that are greater than the guideline
def fill_exceedances(x):
color = 'orange'
#get columns which are in keys of dict
c = x.columns.intersection(ANZECC.keys())
#filter columns and rename by dict
df2 = x[c].rename(columns=ANZECC)
#create boolean mask only for matched columns and compare
mask = df2.astype(float).values < df2.columns[None,:].values
#new DataFrame filled by no color
df1 = pd.DataFrame('', index=x.index, columns=c)
#set color by mask and add missing non matched columns names by reindex
df1 = (df1.where(mask, 'background-color: {}'.format(color))
.reindex(columns=x.columns, fill_value=''))
return df1
df.style.apply(fill_exceedances, axis=None).to_excel('styled.xlsx', engine='openpyxl')
对于ANZECC指南,这给出了
我无法弄清楚如何应用连续样式,因为如果重复此过程,以前的样式会丢失。我觉得我走错了路,并且从最低准则到后续的连续样式都行不通。
更新:我将这些准则放入一本词典中,可以根据所使用的准则对其进行排序并指定颜色,但是我对如何进行操作感到困惑。
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}}
df=pd.DataFrame.from_records(guidelines).T
df
赠予:
Out[3]:
Cd Cu Pb Sulphate Zn
ANZECC_FW 0.0002 0.0014 0.0034 1000.0 0.008
ANZECC_Stock 0.0100 0.4000 NaN 1000.0 20.000
CEPA_FW 0.0100 1.0000 0.0050 1000.0 5.000
然后使用以下方法对准则进行排序并分配颜色:
fill_color={'ANZECC_FW':'blue',
'CEPA_FW' :'green',
'ANZECC_Stock': 'yellow'}
for i in df.columns:
col=df[i]
col=col.sort_values(ascending=True)
#print col,i, col.idxmax()
#print i
#print col
count=0
for val in col:
if val>0:
print i,val,col.index[count],fill_color[col.index[count]]
count+=1
else:
continue
礼物:
Cd 0.0002 ANZECC_FW blue
Cd 0.01 ANZECC_Stock yellow
Cd 0.01 CEPA_FW green
Cu 0.0014 ANZECC_FW blue
Cu 0.4 ANZECC_Stock yellow
Cu 1.0 CEPA_FW green
Pb 0.0034 ANZECC_FW blue
Pb 0.005 CEPA_FW green
Sulphate 1000.0 ANZECC_FW blue
Sulphate 1000.0 ANZECC_Stock yellow
Sulphate 1000.0 CEPA_FW green
Zn 0.008 ANZECC_FW blue
Zn 5.0 CEPA_FW green
Zn 20.0 ANZECC_Stock yellow
所以我拥有所有信息,我只需要遍历这些信息,以便数据中的每一列(如果单元格值> =列表值,则指定填充颜色)就可以正常工作,但我仍然坚持如何应用这个。
答案 0 :(得分:2)
首先,您的问题很少:
您的数据不一致:用于生成df
的代码包含一些混合了浮点数的字符串。如果您的数据确实是这种情况,那么您应该做的第一件事就是将所有内容都转换为float:
df = df.apply(pd.to_numeric)
您在整个帖子中的guidelines
更改。例如:
您从准则开始
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}
然后,稍后再构建您的guidelines
数据框,您也必须错误地将其命名为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
和fill_color
:
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)
输出:
答案 1 :(得分:1)
看来这是您可以采取的方法:
编辑:
;; With
(defun add (x y) (+ x y))
(defun mul (x y) (* x y))
;; I want to have this:
(let-curry 1000 (add mul)
(print (add 3))
(print (mul 3)))
;; expanding to:
(flet ((add (y) (add 1000 y))
(mul (y) (mul 1000 y)))
(print (add 3))
(print (mul 3)))
;; but instead I'm getting:
Execution of a form compiled with errors.
Form:
(FLET (LOOP
FOR
#1=#:G777
IN
(ADD MUL
)
COLLECT
(LIST #1#
(&REST ARGS)
(FUNCALL #1# 1000 ARGS)))
(PRINT (ADD 3))
(PRINT (MUL 3)))
Compile-time error:
The FLET definition spec LOOP is malformed.
[Condition of type SB-INT:COMPILED-PROGRAM-ERROR]