Here is my DataFrame...
from termcolor import colored
import pandas as pd
data = {'Col1': [0, 15, 10, 5, 20, 17], 'Col2': [11, 6, 3, 16, 21, 8], 'Col3': [2, 17, 12, 7, 22, 9],
'Col4': [3, 8, 13, 18, 3, 23], 'Col5': [4, 19, 8, 11, 6, 20]}
df = pd.DataFrame(data)
Now I'm trying to highlight 3 lagest values in each column with red(1st largest), blue(2nd largest) & magenta(3rd largest) color excluding Col2 & Col4.
I tried as ...
columns_to_exclude = ['Col2', 'Col4']
def highlighted(column):
filtered_df = df.drop(columns=columns_to_exclude)
values = column.nlargest(3).tolist()
colors = []
for x in column:
if x in values:
if x == values[0]:
colors.append(colored(str(x), None, 'on_red'))
elif x == values[1]:
colors.append(colored(str(x), None, 'on_blue'))
elif x == values[2]:
colors.append(colored(str(x), None, 'on_magenta'))
else:
colors.append(colored(str(x), 'white'))
return colors
for col in df.columns:
df[col] = highlighted(df[col])
df.columns = [colored(col, None, 'on_black') for col in df.columns]
print(df.to_string(index=False))
But getting all the 5 columns to be highlighted as par my defined coloured. Where I'm wrong ???? Is there any more shorter and simpler way too ??
You can check for the name
when use apply
:
def hightlight(series, excluded, special_col, special_val):
# handle special case
if series.name == special_col:
special_val = str(special_val)
return series.astype(str).apply(lambda x: colored(x, None, 'on_yellow') if x == special_val else
colored(x, 'white') )
# general case
if series.name in excluded:
return series.astype(str).apply(lambda x: colored(x, 'white'))
colors = pd.Series([(None,'on_red'),(None,'on_blue'), (None,'on_magenta')]
+ [('white',)]*(len(series)-3),
index=series.sort_values(ascending=False).index
).reindex(series.index)
return [colored(str(x), *c) for x,c in zip(series, colors)]
print(df.apply(hightlight, excluded=columns_to_exclude, special_col='Col4', special_val=18)
.rename(columns=lambda x: colored(x, 'white', None))
)
Output