I have the following df
:
import pandas as pd
import numpy as np
arrays = [
np.array(["fruit", "fruit", "fruit","vegetable", "vegetable", "vegetable"]),
np.array(["one", "two", "total", "one", "two", "total"]),
]
df = pd.DataFrame(np.random.randn(6, 4), index=arrays)
df.index.set_names(['item','count'],inplace=True)
I am trying to style df
so that each cell where count == 'total'
is bolded.
I was able to index all rows where count == 'total'
with the following code:
idx = pd.IndexSlice
totals = df.loc[idx[:, 'total'],:]
but when I try to apply a function:
def df_style(val):
return "font-weight: bold"
df.style.applymap(df_style,subset=totals)
I get the following error:
KeyError: 0
df
so that all cells where count == 'total'
are bolded?Here is a similar question, albeit with just a regular index rather than MultiIndex.
Here's one approach:
# used `np.random.seed(0)` for reproducibility
def highlight_total(s):
m = s.index.get_level_values('count') == 'total'
return np.where(m, 'font-weight: bold', None)
df.style.apply(highlight_total)
Output:
Explanation
index.get_level_values
equals 'total'.np.where
.Styler.apply
.Specifically traversing the df
row-wise, you could do:
def highlight_total(s):
return ['font-weight: bold']*len(s) if s.name[1] == 'total' else [None]*len(s)
df.style.apply(highlight_total, axis=1)
So, here we are accessing s.name[1]
, with name understood as ('fruit', 'total')
, ('vegetable', 'total')
, etc. Leads to the same result.