'Highlight element based on boolean pandas df
I have 2 data frames with identical indices/columns:
df = pd.DataFrame({'A':[5.5, 3, 0, 3, 1],
'B':[2, 1, 0.2, 4, 5],
'C':[3, 1, 3.5, 6, 0]})
df_bool = pd.DataFrame({'A':[0, 1, 0, 0, 1],
'B':[0, 0, 1, 0, 0],
'C':[1, 1, 1, 0, 0]})
I want to apply a style function to df element-wise using df_bool as a mask.
This is the expected result:
Current failed function
def color_boolean(val):
color =''
if df_bool == 1:
color = 'red'
elif df_bool == 0:
color = 'black'
return f'color: {color}'
df.head().style.apply(color_boolean, axis=None)
ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
Solution 1:[1]
You can use a function that ignores the input and simply uses the other DataFrame:
def color_boolean(val):
return f'color: {"red" if val else "black"}'
df.style.apply(lambda _: df_bool.applymap(color_boolean), axis=None)
or:
df.style.apply(lambda c: df_bool[c.name].apply(color_boolean))
output:
Solution 2:[2]
You can also use np.where to convert df_bool
into a DataFrame of styles based on the locations of 1
values (df_bool.eq(1)
).
By setting axis=None
to Styler.apply we can effectively apply styles to the entire DataFrame.
true_css = 'color:red'
false_css = '' # No Styles (Change if needed)
df.style.apply(
lambda _: np.where(df_bool.eq(1), true_css, false_css),
axis=None
)
Optional format to round and match shown output:
true_css = 'color:red'
false_css = ''
df.style.apply(
lambda _: np.where(df_bool.eq(1), true_css, false_css),
axis=None
).format(formatter='{:1g}')
Imports (and versions):
import numpy as np # 1.22.3
import pandas as pd # 1.4.2
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | mozway |
Solution 2 |