Pandas Dataframe Examples: Styling Cells and Conditional Formatting
Last updated:- Style cell if condition
- Row-wise style
- Highlight cell if largest in column
- Apply style to column only
- Chain styles
- Multiple styles in same function
All code available on this jupyter notebook
Style cell if condition
Here we apply elementwise formatting, because the logic only depends on the single value itself.
Use df.applymap(styler_function)
where styler_function
takes a cell value and returns a CSS style
Example: Change background color for even numbers
import pandas as pd
df = pd.DataFrame({
"name": ["alan","beth","charlie","david", "edward"],
"age" : [34, 12, 43, 32, 77],
"num_children": [1, 0, 2, 1, 6],
"num_pets": [1, 0, 1, 2, 0],
"bank_balance": [100.0, 10.0, -10.0, 30.0, 30.0]})
def even_number_background(cell_value):
highlight = 'background-color: darkorange;'
default = ''
if type(cell_value) in [float, int]:
if cell_value % 2 == 0:
return highlight
return default
df.style.applymap(is_even_background)
background changed
Row-wise style
In other words: for row, take all values and decide which ones to style.
Use df.style.apply(func, axis=1)
. Use subset=[cols]
to limit application to some columns only.
Example: Highlight whether each person has more children or more pets
import pandas as pd
df = pd.DataFrame({
"name": ["alan","beth","charlie","david", "edward"],
"age" : [34, 12, 43, 32, 77],
"num_children": [1, 0, 2, 1, 6],
"num_pets": [1, 0, 1, 2, 0],
"bank_balance": [100.0, 10.0, -10.0, 30.0, 30.0]})
def more_children_or_more_pets_background(row):
highlight = 'background-color: lightcoral;'
default = ''
# must return one string per cell in this row
if row['num_children'] > row['num_pets']:
return [highlight, default]
elif row['num_pets'] > row['num_children']:
return [default, highlight]
else:
return [default, default]
df.style.apply(more_children_or_more_pets_background, subset=['num_children', 'num_pets'], axis=1)
than pets, while David has more
pets than children.
Highlight cell if largest in column
That is, column-wise styling.
Use df.style.apply(func, axis=0)
Example: Change background colour in the maximum values for num_children
and num_pets
:
import pandas as pd
df = pd.DataFrame({
"name": ["alan","beth","charlie","david", "edward"],
"age" : [34, 12, 43, 32, 77],
"num_children": [1, 0, 2, 1, 6],
"num_pets": [1, 0, 1, 2, 0],
"bank_balance": [100.0, 10.0, -10.0, 30.0, 30.0]})
def maximum_value_in_column(column):
highlight = 'background-color: palegreen;'
default = ''
maximum_in_column = column.max()
# must return one string per cell in this column
return [highlight if v == maximum_in_column else default for v in column]
df.style.apply(maximum_value_in_column, subset=['num_children', 'num_pets'], axis=0)
and num_pets are 6 and 2,
respectively.
Apply style to column only
In order to restrict application of some style to some columns, use subset=[cols]
:
df.style.apply(func, subset=['col1'], axis=1)
to applyfunc
rowwise to column'col1'
onlydf.style.apply(func, subset=['col2'], axis=0)
to applyfunc
columnwise to column'col2'
only
Chain styles
In other words, apply multiple styles one after the other:
In this example:
- use red font for negative values in
bank_balance
- write the highest age in bold
- use light red background for zero values in
num_children
andnum_pets
import pandas as pd
df = pd.DataFrame({
"name": ["alan","beth","charlie","david", "edward"],
"age" : [34, 12, 43, 32, 77],
"num_children": [1, 0, 2, 1, 6],
"num_pets": [1, 0, 1, 2, 0],
"bank_balance": [100.0, 10.0, -10.0, 30.0, 30.0]})
def red_font_negatives(series):
highlight = 'color: red;'
default = ''
return [highlight if e < 0 else default for e in series]
def bold_max_value_in_series(series):
highlight = 'font-weight: bold;'
default = ''
return [highlight if e == series.max() else default for e in series]
def red_background_zero_values(cell_value):
highlight = 'background-color: tomato;'
default = ''
if cell_value == 0:
return highlight
else:
return default
(df
.style
.apply(red_font_negatives, axis=0, subset=['bank_balance'])
.apply(bold_max_value_in_series, axis=0, subset=['age'])
.applymap(red_background_zero_values))
largest age in bold, zero values in
pets or children and negative
bank balances.
Multiple styles in same function
You can use multiple else
clauses in a ternary if-else condition too:
import pandas as pd
df = pd.DataFrame({
"name": ["alan","beth","charlie","david", "edward"],
"bank_balance": [100.0, 10.0, -10.0, 30.0, 30.0]})
def colour_numbers(series):
red = 'background-color: red;'
orange = 'background-color: orange;'
default = ''
# note multiple else ..if conditions
return [red if e < 0 else orange if e < 15 else default for e in series]
(df
.style
.apply(colour_numbers, axis=0, subset=['bank_balance']))
two conditions and depending
on which one matched, the cell
gets a different colour