I have a dataframe with 3 kind of data types - int64
, float64
and object
(string). How to apply format for two different data types in one function?
Sample:
def abc_style_format(cell_val):
default = ""
style_a = "background-color: green"
style_b = "background-color: gold"
style_c = "background-color: salmon"
style_float = "precision=2"
match cell_val:
case "A":
return style_a
case "B":
return style_b
case "C":
return style_c
if type(cell_val) == "float64":
return style_float
return default
df_abc.style.map(abc_style_format)
Block match
/case
works properly, but part precision=2
doesn't work.
The result:
Here is one way to do it by defining as many helper functions as needed:
import pandas as pd
def _abc_style_format(s: pd.Series) -> list[str]:
"""Helper function to format 'abc' columns.
Args:
s: target column.
Returns:
list of styles to apply to each target column cell.
"""
background_colors = []
for v in s:
match v:
case "A":
background_colors.append("background-color: green")
case "B":
background_colors.append("background-color: gold")
case "C":
background_colors.append("background-color: salmon")
return background_colors
def _qty_format(s: pd.Series) -> list[str]:
"""Helper function to format 'qty' column.
Args:
s: target column.
Returns:
list of styles to apply to each target column cell.
"""
font_colors = []
for v in s:
if v > 150:
font_colors.append("color: red")
else:
font_colors.append("color: green")
return font_colors
And one main function:
from pandas.io.formats.style import Styler
def style(df: pd.DataFrame) -> Styler:
"""Function to style whole dataframe.
Args:
df: target dataframe.
Returns:
styled dataframe.
"""
styler = df.style
for col in df.columns:
match df[col].dtype:
case "object":
styler = styler.apply(_abc_style_format, subset=col)
case "float64":
styler = styler.format(precision=2, subset=col)
case "int64":
styler = styler.apply(_qty_format, subset=col)
case _:
pass
return styler
Then, with the following toy dataframe:
df = pd.DataFrame(
{
"description": ["product1", "product2", "product3"],
"qty": [130, 160, 110],
"gm": [43.20000, 40.70000, 35.20000],
"abc_gm_category": ["A", "B", "C"],
"abc_amount_category": ["C", "A", "B"],
}
)
You can simply do:
styled_df = style(df)
styled_df
Which gets you the expected output: