Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pandas: HTML output with conditional formatting

I am trying to format a table, such that data in each column are formatted in a style depending on their values (similar to conditional formatting in spreadsheet programs). How can I achieve that in pandas using the HTML formatter?

A typical use case is highlighting significant values in a table. For example:

    correlation  p-value 0   0.5          0.1 1   0.1          0.8 2   0.9          *0.01* 

pandas allows to define custom formatters for HTML output - to obtain above output one could use:

import pandas as pd from pandas.core import format from StringIO import StringIO buf = StringIO() df = pd.DataFrame({'correlation':[0.5, 0.1,0.9], 'p_value':[0.1,0.8,0.01]}) fmt = format.DataFrameFormatter(df,            formatters={'p_value':lambda x: "*%f*" % x if x<0.05 else str(x)}) format.HTMLFormatter(fmt).write_result(buf) 

However, I would like to change the style for significant values (for example, by using bold font).

A possible solution would be to attach a CSS class to <td> tags in the HTML output, which could be then formatted using CSS stylesheet. The above would then become:

<table border="1" class="dataframe">   <thead>     <tr style="text-align: right;">       <th></th>       <th>correlation</th>       <th>p_value</th>     </tr>   </thead>   <tbody>     <tr>       <td>0</td>       <td> 0.5</td>       <td> 0.10</td>     </tr>     <tr>       <td>1</td>       <td> 0.1</td>       <td> 0.80</td>     </tr>     <tr>       <td>2</td>       <td> 0.9</td>       <td class='significant'> 0.01</td>     </tr>   </tbody> </table> 

Edit: As suggested by @Andy-Hayden I can add formatting by simply replacing stars with <span class="signifcant">...</span> in my example:

import pandas as pd from StringIO import StringIO buf = StringIO() significant = lambda x: '<span class="significant">%f</span>' % x if x<0.05 else str(x) df = pd.DataFrame({'correlation':[0.5, 0.1,0.9], 'p_value':[0.1,0.8,0.01]}) df.to_html(buf, formatters={'p_value': significant}) 

Newer versions of pandas escape the tags. To avoid it replace last line with:

df.to_html(buf, formatters={'p_value': significant}, escape=False) 
like image 287
btel Avatar asked Jan 31 '13 13:01

btel


1 Answers

You can use the DataFrame to_html method, which comes with formatters argument.

An easier solution would be to surround by <span class="significant"> and </span>, (rather than *). Note: by default this will be escaped (i.e. < becomes &lt;) so you will need to use the escape=False argument.

like image 54
Andy Hayden Avatar answered Sep 18 '22 23:09

Andy Hayden