I have the following dataframe:
dic = {'US':{'Quality':{'points':"-2 n", 'difference':'equal', 'stat': 'same'}, 'Prices':{'points':"-7 n", 'difference':'negative', 'stat': 'below'}, 'Satisfaction':{'points':"3 n", 'difference':'positive', 'stat': 'below'}},
'UK': {'Quality':{'points':"3 n", 'difference':'equal', 'stat': 'above'}, 'Prices':{'points':"-13 n", 'difference':'negative', 'stat': 'below'}, 'Satisfaction':{'points':"2 n", 'difference':'negative', 'stat': 'same'}}}
d1 = defaultdict(dict)
for k, v in dic.items():
for k1, v1 in v.items():
for k2, v2 in v1.items():
d1[(k, k2)].update({k1: v2})
df = pd.DataFrame(d1)
print(df)
I have to format the style of the cells as per the logic below:
#1.
# If the difference is negative, then the font color of the points cell is red,
# else if the difference is equal, then the font color of the points cell is grey
#2.
#If stat is below or above, then the font color of the stat cell is red and the background color is blue
You can apply conditional styling on your multi-level dataframe by first defining the following helper functions:
# 1. If the difference is negative, then the font color of the points cell is red,
# else if the difference is equal, then the font color of the points cell is grey
def red_if_negative(s, **kwargs):
return ["color: red" if v == "negative" else "" for v in df[(col, "difference")]]
def grey_if_equal(s, **kwargs):
return ["color: lightgrey" if v == "equal" else "" for v in df[(col, "difference")]]
# 2. If stat is below or above, then the font color of the stat cell is red
# and the background color is blue.
def red_on_blue_if_below_or_above(s, **kwargs):
is_above = (s == "below") | (s == "above")
return [
"background-color: lightsteelblue; color: red" if v else "" for v in is_above
]
Then:
styler = df.style
for (func, subset, col) in [
(red_on_blue_if_below_or_above, [("US", "stat"), ("UK", "stat")], None),
(red_if_negative, [("US", "points")], "US"),
(red_if_negative, [("UK", "points")], "UK"),
(grey_if_equal, [("US", "points")], "US"),
(grey_if_equal, [("UK", "points")], "UK"),
]:
syler = styler.apply(func, subset=subset, col=col)
styler
Outputs in a Jupyter notebook: