Pandas: How to use termcolor for highlighting largest values in selected columns

I have a DataFrame…
data = {‘Col1’: [10, 15, 20, 25, 30, 35], ‘Col2’: [15, 20, 25, 30, 35, 40], ‘Col3’: [22, 27, 32, 37, 42, 47], ‘Col4’: [23, 28, 33, 38, 43, 48], ‘Col5’: [14, 19, 24, 31, 36, 41]}
df = pd.DataFrame(data)

I want to highlight red the 3 largest values of Col3 & Col4.
Haw can I do that with termcolor ???

Hi - When you post code, please use the triple-backquote around code blocks. The editor makes this easy.

You probably know that if you’re working in a Jupyter notebook, you don’t need termcolor to do this. Pandas has elaborate styling functionality: Table Visualization — pandas 2.1.0 documentation

import pandas as pd
data = {'Col1': [10, 15, 20, 25, 30, 35], 
        'Col2': [15, 20, 25, 30, 35, 40], 
        'Col3': [22, 27, 32, 37, 42, 47],
        'Col4': [23, 28, 33, 38, 43, 48], 
        'Col5': [14, 19, 24, 31, 36, 41]
}
df = pd.DataFrame(data)

def highlight_max(col, props=''):
    nlargest = col.nlargest(3)
    return np.where(col.isin(nlargest), props, '')

df.style.apply(highlight_max, props='color:red', subset=['Col3', 'Col4'], axis=0)

This doesn’t work on the command line, since Pandas uses CSS-styling for formatting. I’m not sure if there is any easy tool to do this (tabulate doesn’t seem to have a way to apply colors), but it’s not too hard to use termcolor (or just plug in ANSI color codes yourself): Select the wanted cells, then replace the values with their colored string values. This does mess up rendering of the headers and column alignment in printing - but if you use tabulate to print, tabulate will correct for the ANSI codes.
Something like this:

from termcolor import colored
import tabulate
df1 = pd.DataFrame(df)
nl3 = df.Col3.nlargest(3).values
nl4 = df.Col4.nlargest(3).values
df1.Col3 = df1.Col3.apply(lambda x: colored(x, "red") if x in nl3 else x)
df1.Col4 = df1.Col4.apply(lambda x: colored(x, "red") if x in nl4 else x)
print(tabulate.tabulate(df1, headers=df1.columns))

I wonder if there is a less klunky way of doing this - If somebody knows one, I’d like to know too :slight_smile:

1 Like