Sharvari Gc
Sharvari Gc

Reputation: 721

DataFrame Styling based on conditions for groups of columns

I need to style a Dataframe:

df = DataFrame({'A':['Bob','Rob','Dob'],'B':['Bob', 'Rob','Dob'],'C':['Bob','Dob','Dob'],'D':['Ben','Ten','Zen'],'E':['Ben','Ten','Zu']})
df
     A  B    C  D   E
0   Bob Bob Bob Ben Ben
1   Rob Rob Dob Ten Ten
2   Dob Dob Dob Zen Zu

I need to compare columns - A,B, C at once to check if they are equal and then apply a highlight/color to unequal values. Then I need to compare columns D,E to check if they are equal and then apply a highlight/color to unequal values

like:

df[['A','B','C']].eq(df.iloc[:, 0], axis=0)

     A       B       C
0   True    True    True
1   True    True    False
2   True    True    True

I am unable to apply df.style with a subset of df and then concat.

Response to answer by @jezrael: enter image description here

Upvotes: 0

Views: 1193

Answers (1)

jezrael
jezrael

Reputation: 862661

I believe need:

def highlight(x):
    c1 = 'background-color: red'
    c2 = '' 
    #define groups of columns for compare by first value of group ->
    #first with A, second with D
    cols = [['A','B','C'], ['D','E']]

    #join all masks together
    m = pd.concat([x[g].eq(x[g[0]], axis=0) for g in cols], axis=1)
    df1 = pd.DataFrame(c2, index=x.index, columns=x.columns)
    df1 = df1.where(m, c1)
    return df1

df.style.apply(highlight, axis=None)

pic

EDIT: For multiple colors is possible create dictionary by colors with columns for compare:

def highlight(x):
    c = 'background-color: '
    cols = {'red': ['A','B','C'], 'blue':['D','E']}

    m = pd.concat([x[v].eq(x[v[0]], axis=0).applymap({False:c+k, True:''}.get) 
                   for k, v in cols.items()], axis=1)
    return m

pic2

EDIT1:

Alternative solution:

def highlight(x):
    c = 'background-color: '
    cols = {'red': ['A','B','C'], 'blue':['D','E']}

    df1 = pd.DataFrame(c, index=x.index, columns=x.columns)

    for k, v in cols.items():
        m = x[v].eq(x[v[0]], axis=0).reindex(columns=x.columns, fill_value=True)
        df1 = df1.where(m, c+k)
    return df1    

df.style.apply(highlight, axis=None)

Upvotes: 2

Related Questions