我正在尝试使用 pandas 1.3.5 隐藏 pandas Styler 的索引级别。 即复制 pandas 1.4 中 hide(axis="index", level="level_name")
的行为。
这是我正在尝试的一个最小示例:
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)
)
添加一些边框,它会生成下表:
现在为了隐藏“index”索引级别,我尝试通过添加 CSS 样式来实现此目的 answer ,如下:
.set_table_styles([{'selector': 'tr th:nth-child(3), tr td:nth-child(3)', 'props': [
('display', 'None')]}], overwrite=False)
但它给了我这个结果:
最佳答案
pandas 1.3.5 中有一些选项,尽管这是一个不使用 hide
的不简单的操作。该功能在 1.4.0 中可用。
删除索引级别 >= 1
nth-child
由于在多重索引中使用行跨度,此处不起作用。但是,我们可以利用 Styler 添加的默认 CSS 类 ( style.py L158-L171 ):
Index and Column names include
index_name
andlevel<k>
wherek
is its level in a MultiIndexIndex label cells include
row_heading
row<n>
wheren
is the numeric position of the rowlevel<k>
wherek
is the level in a MultiIndexColumn label cells include
col_heading
col<n>
wheren
is the numeric position of the columnlevel<k>
wherek
is the level in a MultiIndexBlank cells include
blank
所以我们可以简单地排除 CSS 选择器 .level2:not(.col_heading)
哪里n
是我们想要隐藏的级别(level0 需要稍作修改)。我们需要排除 col_heading,这样我们就不会删除任何列标题。
此外,我们还需要删除 blank
之一级别,以便顶层对齐。我采取了简单的方法,并选择删除每行的第一个空白。
注意:这不是一个持久的解决方案,并且会受到 MultiIndex 列等结构更改的影响。
这是一个使用样式隐藏级别 2 的示例
hide_column_styles = [
{
# Remove all row values associated with level2
'selector': f'th.level2:not(.col_heading)',
'props': [('display', 'none')]
},
{
# Remove the first th in each row if it is .blank
'selector': 'thead th:first-child.blank',
'props': [('display', 'none')]
}
]
# Basic border
border_styles = [{
'selector': '',
'props': [('border-collapse', 'collapse')]
}, {
'selector': 'table, th, td',
'props': [('border', '1px solid black')]
}]
(
data.reset_index()
.set_index(["Ex Date", "Portfolio", "index"])
.style
.apply(multi_highlighter, range_colors=range_colors, axis=1)
.set_table_styles([*hide_column_styles, *border_styles])
)
删除索引级别 0
如果尝试删除 level0,我们只需要隐藏 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')]
}
]
第一个索引列将具有类 .level0 并隐藏,无需额外的选择器:
<tr>
<th class="blank"> </th>
<th class="blank"> </th>
<th class="blank level0"> </th> <!-- This will match and be hidden -->
<th class="col_heading level0 col0">Position</th>
<th class="col_heading level0 col1">Strike</th>
</tr>
隐藏不影响多索引唯一性的级别
如果索引级别在删除级别后仍保持唯一,则可以仅 droplevel在创建 Styler 之前删除索引:
例如,下面是通过删除级别 0 来删除它的示例。
n = 0 # level to drop
(
data
.reset_index()
.set_index(["Ex Date", "Portfolio", "index"])
.droplevel(level=n) # Drop level from DataFrame
.style
.apply(multi_highlighter, range_colors=range_colors, axis=1)
.set_table_styles([
{
'selector': 'table, th, td',
'props': [('border', '1px solid black')]
}
])
)
注意:仅当 MultiIndex 在删除级别后唯一时才有效
如果某个级别被删除导致非唯一的 MultiIndex(如级别 2),则在使用 Styler.apply
时将出现 KeyError或Styler.applymap
:
KeyError: '
Styler.apply
and.applymap
are not compatible with non-unique index or columns.'
Pandas 1.4.0 及更高版本
为了让 future 的读者清楚地了解这个问题,这是 1.4.0 之前版本的解决方法。使用 hide 简单得多。功能和解决方案比 CSS 选择器更耐用:
n = 2 # level to drop
border_styles = [{
'selector': '',
'props': [('border-collapse', 'collapse')]
}, {
'selector': 'table, th, td',
'props': [('border', '1px solid black')]
}]
(
data
.reset_index()
.set_index(["Ex Date", "Portfolio", "index"])
.style
.apply(multi_highlighter, range_colors=range_colors, axis=1)
.hide(axis=0, level=n)
.set_table_styles(border_styles)
)
关于html - 如何隐藏 pandas <1.4 中的索引级别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72700845/