Python – How to apply css formatting to pd. The DataFrame does not display index columns

How to apply css formatting to pd. The DataFrame does not display index columns… here is a solution to the problem.

How to apply css formatting to pd. The DataFrame does not display index columns

In short, my goal is to display a “normal” looking table in my html page (i.e. all headers in one row, no row numbers) and each cell color-coded according to the rule lookup (with the flexibility to look up different rules for each cell. My data is stored in PD. DataFrame object. Sometimes my data is better represented as pivot tables (multiple indexes). The format is a requirement for the end user. File system access is very limited, and all of them are multithreaded, so I don’t really have the option to write html and then read-modify-write.

Some information about the operating environment:

  • python 3.5.2
  • Pandas version 0.19.2
  • Requires both x86 and x64 runs
  • Requires running on Windows and Linux

Example settings:

import pandas as pd
import numpy as np
df = pd. DataFrame()
df['special_col_1'] = pd. Series([0,0,0,1,1,1])
df['special_col_2'] = pd. Series([0,1,2,0,1,2])
df['a'] = pd. Series(np.random.randn(6)).apply(lambda x: int(x*100))
df['b'] = pd. Series(np.random.randn(6)).apply(lambda x: int(x*100))
df['c'] = pd. Series(np.random.randn(6)).apply(lambda x: int(x*100))

basic_limits = {'a': lambda x: 'background-color: red' if x < 0 else 'background-color: green',\
                'b': lambda x: 'background-color: red' if x < 10 else 'background-color: green', \
                'c': lambda x: 'background-color: red' if x > 20 else 'background-color: green', \
                'special_col_1': lambda x: 'background-color: white', \
                'special_col_2': lambda x: 'background-color: white'}

Examples I’ve tried and why I don’t like them:

df.to_html(index=False)

Everything is arranged
No way to apply CSS to every cell

pd.pivot_table(data=df, columns=['special_col_1', 'special_col_2']).to_html(index=False)

The layout is incorrect, and the first line should contain all the labels
No way to apply CSS to every cell

dfs = df.style
for col in df.columns:
    dfs.applymap(basic_limits[col], subset=col)

Incorrect layout – there should be no line numbers (indexes), but once you start with pd. DataFrame Go to pd. DataFrame.Styler couldn’t find any way to drop the index
CSS styles
can be applied correctly using a dictionary of lambda functions
Can be modified to iterate through rows and columns, and applymap() still works (a multi-level dictionary of more complex lambda functions is required).

df.pivot_table(data=df, columns=???). style(...)

Specify [‘special_col_1’, ‘special_col_2’] to break the formatting
of the top row again
Not specifying any column is Not Acceptable (‘ValueError: No passing group key!’).
Has to act as pd. All the advantages and disadvantages of the DataFrame.Styler object

Any help would be appreciated! Sorry, I can’t include a picture of the table, this is my first post.


The Confirmed Working Answer (piRSquared) provides the active :

df = pd. DataFrame()
dfs = df.style

#iterate through dataframe's columns, applying custom function to each cell in the column
for col in df.columns: 
    dfs.applymap(cell_based_function_dict[col], subset=col)

#apply a function to each column
col_based_function = lambda c: pd. Series(['background-color: white' if c.name in ['special_col_1', 'special_col_2'] else 'background-color: red' if x == c.max() else 'background-color: orange' if x > 0 else ' background-color: green' for x in c])
dfs.apply(col_based_function)

#define css specifics for this particular table
styler.set_table_styles([\
    {'selector': 'tr :first-child', 'props': [('display', 'none')]}, \
    {'selector': 'tr:hover td', 'props': [('background-color',  'yellow')]}, \
    {'selector': 'th, td', 'props': [('border', '1px solid black'), \
                                     ('padding', '4px'), \
                                     ('text-align', 'center')]}, \
    {'selector': 'th', 'props': [('font-weight', 'bold')]}, \
    {'selector': '', 'props': [('border-collapse', 'collapse'),\
                               ('border', '1px solid black')]} \
    ])

#all the styling appears to be tied only to this particular dataframe table, so you can easily call render() on different tables of different styles
dfs.render()

Solution

You can use pd. DataFrame.style.set_table_styles

We can go ahead and use the same styler object and update it.

dfs = df.style
for col in df.columns:
    dfs.applymap(basic_limits[col], subset=col)

dfs.set_table_styles([
    {'selector': 'tr :first-child',
     'props': [('display', 'none')]}
])

enter image description here

You can use ; Suppress the output and still get the html

dfs = df.style
for col in df.columns:
    dfs.applymap(basic_limits[col], subset=col)

dfs.set_table_styles([
    {'selector': 'tr :first-child',
     'props': [('display', 'none')]}
]);

my_html = dfs.render()

Related Problems and Solutions