I'm trying to style a simple multiplication table. I have the following rule, and if a cell doesn't satisfy it, I must colorize it in a different color.
Example 1: Given numbers 10 and 11, the rule is broken since -798010 != 110, so the color is red:
(100-(100-10)-(100-11)) = -79
and (100-10)*(100-11) = 8010
as strings: -79801010*11
: 110Example 2: Given numbers 10 and 99, the rule is satisfied since 990 == 990, so the color is green.
(100-(100-10)-(100-99)) = 9
and (100-10)*(100-99) = 90
as strings: 99010*90
: 990Currently I'm checking if numbers are in the rule or not. Either way I colorize cells, all I get is all cells in one color:
import pandas as pd
l = []
for i in range(10, 100):
for j in range(10, 100):
l.append(f'{i}*{j}')
result = [l[idx:idx+90] for idx in range(0, len(l), 90)]
df = pd.DataFrame(result)
def style_dataframe(s):
for row_index, row in df.iterrows():
for col_name, cell in row.items():
if int(cell[:2])*int(cell[3:5]) == int(str(100 - ((100 - (int(cell[:2])))-(100-(int(cell[3:5])))))+str((100-(int(cell[:2])))*int(int(cell[3:5])))):
return 'background-color: green'
elif int(cell[:2])*int(cell[3:5]) != int(str(100 - ((100 - (int(cell[:2])))-(100-(int(cell[3:5])))))+str((100-(int(cell[:2])))*int(int(cell[3:5])))):
return 'background-color: red'
s = df.style.applymap(style_dataframe)
df.style.applymap
operates elementwise, so the styling function expects only 1 cell (not a dataframe)100-(100-a)-(100-b)
can be simplified to just a+b-100
So the styling function should look something like this:
def rule(cell):
a, b = map(int, cell.split('*')) # split 'a*b' into [a, b]
cond1 = str(a+b-100) + str((100-a)*(100-b)) # string version
cond2 = a * b # multiplication version
color = 'green' if int(cond1) == cond2 else 'red' # check rule
return f'background-color: {color}' # return css style
df.style.applymap(rule)
As a side note, it's much simpler to create the original df
with numpy broadcasting:
a = np.arange(10, 100).astype(str)
df = pd.DataFrame(np.char.add(np.char.add(a[:, None], '*'), a))
# 0 1 2 ... 87 88 89
# 0 10*10 10*11 10*12 ... 10*97 10*98 10*99
# 1 11*10 11*11 11*12 ... 11*97 11*98 11*99
# 2 12*10 12*11 12*12 ... 12*97 12*98 12*99
# .. ... ... ... ... ... ... ...
# 87 97*10 97*11 97*12 ... 97*97 97*98 97*99
# 88 98*10 98*11 98*12 ... 98*97 98*98 98*99
# 89 99*10 99*11 99*12 ... 99*97 99*98 99*99
#
# [90 rows x 90 columns]