'Python: simple mapping of dataframe styler
I am stuck on figuring out how to map a pre-existing df of styling options to a df of integers:
import numpy as np
import pandas as pd
# Create a 9 x 3 array of integers
random_state = np.random.RandomState(seed=44)
myArray = random_state.randint(0,9, (9,3))
Which gives the output:
[[4 3 1]
[3 0 4]
[3 8 7]
[7 6 3]
[7 3 3]
[6 5 4]
[5 1 8]
[7 4 5]
[3 0 4]]
Then create a random 2D list of 'color: option' to be mapped onto myArray with the styler:
styleList = []
colorOptions = ['color: lime','color: red','color: yellow']
for i in arr:
inner = []
for j in i:
inner.append(np.random.choice(colorOptions))
styleList.append(inner)
for i in styleList: print(i)
Check the output:
['color: yellow', 'color: lime' , 'color: red']
['color: red' , 'color: lime' , 'color: red']
['color: yellow', 'color: yellow', 'color: yellow']
['color: yellow', 'color: red' , 'color: lime']
['color: yellow', 'color: red' , 'color: yellow']
['color: red' , 'color: lime' , 'color: yellow']
['color: red' , 'color: yellow', 'color: red']
['color: yellow', 'color: yellow', 'color: yellow']
['color: lime' , 'color: red' , 'color: red']
Convert both of these to dataframes:
df = pd.DataFrame(data=myArray, index=None, columns=['col1', 'col2', 'col3'])
dfStyle = pd.DataFrame(data=styleList, index=None, columns=['col1', 'col2', 'col3'])
Since I already have the dataframe dfStyle
with the styling options, how can I simply map its values to the integer values in df
(and without having to generate dfStyle
within a separate function)?
I'll avoid cluttering this space with my various attempts using df.style.apply()
, df.style.applymap()
and even functions that attempt to simply return dfStyle
, but this seemingly straightforward task has thrown me in circles.
Desired result is a styled df:
df[0][0]
should be the number 4 displayed with the color yellow
df[0][1]
should be the number 3 displayed with the color lime
df[0][2]
should be the number 1 displayed with the color red
etc.
Thanks for any help.
••• UPDATE •••
I figured out how to properly map the style as I wanted by using:
def color(row):
dfs = dfStyle.copy()
x = [dfs.iloc[row.name][j] for i,j in zip(row, dfStyle)]
return x
df.style.apply(color, axis=1)
which results in the desired:
Solution 1:[1]
As posted at the end of my question, I managed to arrive at my desired solution with:
def color(row):
dfs = dfStyle.copy()
x = [dfs.iloc[row.name][j] for i,j in zip(row, dfStyle)]
return x
df.style.apply(color, axis=1)
Although this is indeed the solution I was after, it seems like a rather convoluted and unnecessarily complicated way of getting there.
I would still be grateful to know of a simple and intuitive way to achieve the same.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | ZwiTrader |