I'm trying to hide an index level from a pandas Styler with pandas 1.3.5. i.e. to replicate the behavior of hide(axis="index", level="level_name")
in pandas 1.4.
Here is a minimale example of what I'm trying :
def multi_highlighter(row, range_colors):
def find_color(value):
for color, threshold in range_colors.items():
if value < threshold:
return color
return "white"
return [f"background-color: {find_color(v)}" for v in row]
range_colors = {"red": 18, "orange": 100}
data = pd.DataFrame({
"Ex Date": ['2022-06-20', '2022-06-20', '2022-06-20', '2022-06-20', '2022-06-20', '2022-06-20', '2022-07-30', '2022-07-30', '2022-07-30'],
"Portfolio": ['UUU-SSS', 'UUU-SSS', 'UUU-SSS', 'RRR-DDD', 'RRR-DDD', 'RRR-DDD', 'KKK-VVV', 'KKK-VVV', 'KKK-VVV'],
"Position": [120, 90, 110, 113, 111, 92, 104, 110, 110],
"Strike": [18, 18, 19, 19, 20, 20, 15, 18, 19],
})
(
data
.reset_index()
.set_index(["Ex Date", "Portfolio", "index"])
.style
.apply(multi_highlighter, range_colors=range_colors, axis=1)
)
Adding some borders, it produces the following table:
Now to hide the "index" index level, I tried to achieve this by adding CSS styling from this
CodePudding user response:
There are a few options in pandas 1.3.5, though this is a non-trivial operation without the use of the hide
function available in 1.4.0.
Removing Index Levels >= 1
nth-child
is not working here due to the use of rowspans in the MultiIndex. However, we can take advantage of the default CSS classes that are added by the Styler (
Removing Index level 0
If trying to remove level0 we only need to hide level0:
hide_column_styles = [
{
# Remove all values associated with level0 (including the first header row)
'selector': f'th.level0:not(.col_heading)',
'props': [('display', 'none')]
}
]
The first index column will have the class .level0 and be hidden without needing an additional selector:
<tr>
<th > </th>
<th > </th>
<th > </th> <!-- This will match and be hidden -->
<th >Position</th>
<th >Strike</th>
</tr>
Hiding levels that do not affect MultiIndex Uniqueness
If the index levels would remain unique after removing a level it is possible just to
If a level is dropped causing a non-unique MultiIndex (like level 2) a KeyError will occur when using Styler.apply
or Styler.applymap
:
KeyError: '
Styler.apply
and.applymap
are not compatible with non-unique index or columns.'
Pandas 1.4.0 and newer
Just to be super clear for any future readers of this question, this is a workaround for versions prior to 1.4.0. It is much simpler to use the