Reputation: 3411
Consider the example:
import pandas as pd
pd.options.display.float_format = '{:,.3f}'.format
df = pd.DataFrame.from_dict(dict(name=['a', 'b', 'c'], value=[1.1234,2.123332,3.232433]))
print(df)
df = df.style.apply(lambda x: ['background: lightgreen' if (x.name == 1) else '' for i in x], axis=1)
print(df.to_html())
HTML output:
<style type="text/css">
#T_fa0b6_row1_col0, #T_fa0b6_row1_col1 {
background: lightgreen;
}
</style>
<table id="T_fa0b6">
<thead>
<tr>
<th class="blank level0" > </th>
<th id="T_fa0b6_level0_col0" class="col_heading level0 col0" >name</th>
<th id="T_fa0b6_level0_col1" class="col_heading level0 col1" >value</th>
</tr>
</thead>
<tbody>
<tr>
<th id="T_fa0b6_level0_row0" class="row_heading level0 row0" >0</th>
<td id="T_fa0b6_row0_col0" class="data row0 col0" >a</td>
<td id="T_fa0b6_row0_col1" class="data row0 col1" >1.123400</td>
</tr>
<tr>
<th id="T_fa0b6_level0_row1" class="row_heading level0 row1" >1</th>
<td id="T_fa0b6_row1_col0" class="data row1 col0" >b</td>
<td id="T_fa0b6_row1_col1" class="data row1 col1" >2.123332</td>
</tr>
<tr>
<th id="T_fa0b6_level0_row2" class="row_heading level0 row2" >2</th>
<td id="T_fa0b6_row2_col0" class="data row2 col0" >c</td>
<td id="T_fa0b6_row2_col1" class="data row2 col1" >3.232433</td>
</tr>
</tbody>
</table>
When I apply a style to a row, I notice it invalidates the float_format precision that has been applied. When I dump to HTML, I see 6 digits after the decimal instead of the three. What is the correct way to fix this?
I'm creating a dataframe that has a row called 'Total'. I would like this row to be highlighted only. I dump this to a HTML, and then run weasyprint to generate a PDF. I will have a lot of tables in my PDF. Maybe it is better to create a special CSS class that performs this styling, but how do I assign a CSS class to one row in a dataframe only?
Upvotes: 1
Views: 916
Reputation:
It seems like the styler's output is different from the rest of pandas output, so I guess it doesn't respect pd.options
. Instead, you can use the format
method of Styler
objects.
You can either specify the precision directly:
style = df.style.apply(lambda x: ['background: lightgreen' if (x.name == 1) else '' for i in x], axis=1)
style = style.format(precision=3)
Or, specify a custom formatter:
formatter = {
'value': '{:,.3f}'.format # same as lambda x: '{:,.3f}'.format(x)
}
style = style.format(formatter=formatter)
Output:
>>> print(style.to_html())
<style type="text/css">
#T_95068_row1_col0, #T_95068_row1_col1 {
background: lightgreen;
}
</style>
<table id="T_95068_">
<thead>
<tr>
<th class="blank level0" > </th>
<th class="col_heading level0 col0" >name</th>
<th class="col_heading level0 col1" >value</th>
</tr>
</thead>
<tbody>
<tr>
<th id="T_95068_level0_row0" class="row_heading level0 row0" >0</th>
<td id="T_95068_row0_col0" class="data row0 col0" >a</td>
<td id="T_95068_row0_col1" class="data row0 col1" >1.123</td>
</tr>
<tr>
<th id="T_95068_level0_row1" class="row_heading level0 row1" >1</th>
<td id="T_95068_row1_col0" class="data row1 col0" >b</td>
<td id="T_95068_row1_col1" class="data row1 col1" >2.123</td>
</tr>
<tr>
<th id="T_95068_level0_row2" class="row_heading level0 row2" >2</th>
<td id="T_95068_row2_col0" class="data row2 col0" >c</td>
<td id="T_95068_row2_col1" class="data row2 col1" >3.232</td>
</tr>
</tbody>
</table>
Note the 3-digit precision in the above.
Upvotes: 3