coloring rows in pandas based on integer index

Viewed 180

I would like to color my rows based on my list of integer such that: if my integer is = [3, 10, 12]

the coloring of pandas style should be:

pandas color table

I was trying to do what How to highlight both a row and a column at once in pandas did. but didnt get what i want, snippets of my code:

color = ['red','green','blue','orange','yellow'] 
idx_list = [3, 10, 12]

def color_row(x):
    bc = []
    for i in x:
        for j, idx in enumerate(idx_list):
            c = 'background: '+color[j]
            if x.name <= idx:
                bc.append(c)
    return bc

df.style.apply(color_row,axis=1)

and got this error:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

what did I miss?

1 Answers

To fix your implementation, try iterating over the index instead:

import pandas as pd

color = ['yellow', 'green', 'orange']
idx_list = [3, 10, 12]


def color_row(x):
    bc = []
    for i in x.index:
        for c_i, v in enumerate(idx_list):
            if i <= v:
                bc.append(f'background-color: {color[c_i]}')
                break  # Stop Searching once color is found
    return bc


df.style.apply(color_row)

For a slightly more "pandas" approach try with pd.cut:

import numpy as np
import pandas as pd

np.random.seed(5)
df = pd.DataFrame(np.random.randint(1, 10, (13, 3)), columns=['Name', 'A', 'B'])

# Need Default Value on Upper Bound
color = ['yellow', 'green', 'orange', 'blue']
idx_list = [3, 10, 12]

row_styles = pd.cut(df.index,
                    bins=[np.NINF, *idx_list, np.inf],
                    labels=list(map('background-color: {}'.format, color)))

df.style.apply(lambda _: row_styles)

Some Sample Data:

import numpy as np
import pandas as pd

np.random.seed(5)
df = pd.DataFrame(np.random.randint(1, 10, (13, 3)), columns=['Name', 'A', 'B'])
df.style.apply(color_row_cut)

df:

    Name  A  B
0      4  7  7
1      1  9  5
2      8  1  1
3      8  2  6
4      8  1  2
5      5  7  3
6      2  3  8
7      1  6  1
8      1  5  5
9      4  3  5
10     7  4  4
11     3  2  6
12     8  5  4

Styling Results:

styled Frame

Related