user9094625
user9094625

Reputation:

Conditional styling of a DataFrame using another dataframe

I have two 3X3 pandas DataFrames df1

    A   B   C
0   8   3   9
1   1   7   7
2   3   3   8

and df2.

    A   B   C
0   2   1   2
1   5   9   7
2   1   8   3

What I want to obtain is a tabulated Jupyter Notebook output whose elements are the same as df1 but their font color is red if the element value is greater than the corresponding value of df2. Thus, the expected output is something like the following

    A     B     C
0   8(r)  3(r)  9(r)
1   1     7     7 
2   3(r)  3     8(r)

(r) means the font color of the cell is red, not real printout.


What I tried was applymap method like this

df1.style.applymap(lambda x: 'color : red' if x > df2 else '')

but could not figure out how to set labmda x and df2 on an equal footing. Could anyone help?

Upvotes: 1

Views: 992

Answers (1)

Henry Ecker
Henry Ecker

Reputation: 35626

We should create a DataFrame of styles then Styler.apply on axis=None:

import pandas as pd

df1 = pd.DataFrame({'A': [8, 1, 3], 'B': [3, 7, 3], 'C': [9, 7, 8]})
df2 = pd.DataFrame({'A': [2, 5, 1], 'B': [1, 9, 8], 'C': [2, 7, 3]})

Option 1: compare and replace:

style_df = (
        df1 > df2                  # Compare DataFrames
).replace({
    True: 'background-color:red',  # True Styles
    False: ''                      # False Styles
})

df1.style.apply(lambda _: style_df, axis=None)

Or by creating the style DataFrame directly in the apply call:

df1.style.apply(lambda _: (df1 > df2).replace({
    True: 'background-color:red',
    False: ''
}), axis=None)

Option 2: perhaps more performant, but less idiomatic is np.where:

import numpy as np

df1.style.apply(lambda _: np.where(
    df1 > df2,               # Compare DataFrames
    'background-color:red',  # True Styles
    ''                       # False Styles
), axis=None)

Both produce styled table:

styled df

How the styling is determined with style_df:

                      A                     B                     C
0  background-color:red  background-color:red  background-color:red
1                                                                  
2  background-color:red                        background-color:red

Upvotes: 2

Related Questions