Reputation: 193
I spend my time to solve a problem with coloring table row if the color is basing on a previous row.
In a four point system there is following logic. If 0 or 1 point the row color should be red, if 3 or 4 points the row color should be green and if 2 points the color should be as the row before.
I was not able to determine the previous row color in a dataframe. I solved it with a 'temp' column. Unfortunately this column is shown in the HTML table.
def should_colored(sum_of_points):
if sum_of_points > 2:
return True
elif sum_of_points < 2:
return False
else:
return np.NaN
def determine_coloring_for_row(results):
tmp = pd.DataFrame(results.values, columns=['color_result'])
tmp['color_result'] = tmp['color_result'].apply(lambda i : should_colored(i))
tmp['color_result'].fillna(method='ffill', inplace=True)
return tmp['color_result'].values
def color_row(row, number_of_columns):
color = 'green' if row['color_result'] else 'red'
return ['background-color: %s' % color] * number_of_columns
df['color_result'] = determine_coloring_for_row(df['sum_of_points'])
df.style.apply(color_row, number_of_columns = len(df.columns), axis=1)
Has anybody an idea how to solve it by using style.apply or by hiding the metadata column?
Upvotes: 1
Views: 1210
Reputation: 862731
I think new column is not necessary, need DataFrame of styles
only by original DataFrame
columns and index and set rows by condition with mask
:
def highlight(x):
c1 = 'background-color: green'
c2 = 'background-color: red'
df1 = pd.DataFrame(c2, index=x.index, columns=x.columns)
df1 = df1.mask(df['sum_of_points'].map(should_colored).ffill(), c1)
#print (df1)
return df1
df.style.apply(highlight, axis=None)
Sample:
df = pd.DataFrame({'sum_of_points':[0,1,2,1,2,3,4,1,2,2,4,5,0,1,2],
'A':range(15)})
print (df)
A sum_of_points
0 0 0
1 1 1
2 2 2
3 3 1
4 4 2
5 5 3
6 6 4
7 7 1
8 8 2
9 9 2
10 10 4
11 11 5
12 12 0
13 13 1
14 14 2
def should_colored(sum_of_points):
if sum_of_points > 2:
return True
elif sum_of_points < 2:
return False
else:
return np.NaN
def highlight(x):
c1 = 'background-color: green'
c2 = 'background-color: red'
df1 = pd.DataFrame(c2, index=x.index, columns=x.columns)
df1 = df1.mask(x['sum_of_points'].map(should_colored).ffill(), c1)
return df1
df.style.apply(highlight, axis=None)
Upvotes: 2