我试图用pandas 1.3.5对pandas样式器隐藏索引级别.i.e.复制hide(axis="index", level="level_name")只大Pandas 的行为1.4.

下面是我正在try 的一个简单示例:

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)
)

添加一些边框,将生成下表:

enter image description here

现在,为了隐藏"索引"索引级别,我try 通过在这answer中添加CSS样式来实现这一点,如下所示:

.set_table_styles([{'selector': 'tr th:nth-child(3), tr td:nth-child(3)', 'props': [
    ('display', 'None')]}], overwrite=False)

但它给了我这样的结果:

enter image description here

推荐答案

pandas 1.3.5中有几个选项,尽管这是一个不需要使用1.4.0中可用的hide函数的简单操作.

Removing Index Levels >= 1

由于在多索引中使用了行跨度,nth-child在此不起作用.但是,我们可以利用样式器添加的默认CSS类:

  • 索引和列名包括index_namelevel<k>,其中k是其在多索引中的级别

  • 索引标签单元格包括

    • row_heading
    • row<n>,其中n是行的数字位置
    • level<k>,其中k是多索引中的级别
  • 列标签单元格包括

    • col_heading
    • col<n>,其中n是列的数字位置
    • level<k>,其中k是多索引中的级别

因此,我们可以简单地排除CSS Select 器.level2:not(.col_heading),其中n是我们想要隐藏的任何级别(level0需要稍微修改).我们需要排除col\u标题,以便不删除任何列标题.

此外,我们还需要删除blank个级别中的一个,以便顶层对齐.我采取了简单的方法,并 Select 删除每行的第一个空格.

Note: This is not a durable solution and will be impacted by structure changes like MultiIndex columns.

下面是一个使用样式隐藏level 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])
)

Styler object using display:none to hide level 2


正在删除索引级别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和隐藏,无需额外的 Select 器:

<tr>
  <th class="blank">&nbsp;</th>
  <th class="blank">&nbsp;</th>
  <th class="blank level0">&nbsp;</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即可删除索引before创建样式器:

例如,下面是通过删除级别0来删除级别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')]
        }
    ])
)

注意:只有当多重索引是唯一的after级别被删除时,这才有效

Styler object with level 0 dropped before styling

如果某个级别被删除,导致非唯一的多索引(如级别2),则在使用Styler.applyStyler.applymap时会出现关键错误:

KeyError:"Styler.apply.applymap与非唯一索引或列不兼容."


Pandas 1.4.0及更新版本

为了让这个问题的future 读者非常清楚,这是1.4.0之前版本的一个变通方法.使用hide函数更简单,解决方案比CSS Select 器更耐用:

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)
)

Styler object using the hide function with level=2 to hide level 2

Html相关问答推荐

srcset和大小总是下载最大的

NG8004:找不到名为""的管道.'' [插件Angular 编译器]

如何将grid—template—column应用于元素中的子元素

将CSS应用于TD标记内的div

CSS自定义特性中的URL是否可以相对于定义的CSS文件?

VBA从公共Google Drive地址下载文档-.Click事件(?)

为什么我的网页底部是蓝色背景而不是渐变色?

悬停效果在新西兰表上不起作用

在Firefox中,使用写入模式:Vertical-LR时,不随内容扩展的css弹性项

如何从多个TO中获取一个范围标记以溢出其父标记

多次使用组件时计数Angular 14中嵌套数组的指令

Tailwind CSS 忽略我的元素的填充

按钮悬停效果不影响按钮内的图标

在 laravel 中使用 DomPDF 将数据导出为 pdf 时,第二列被拉伸

Angular中如何向单选按钮添加验证

具有 css 高度的输入元素:100% 溢出父 div

调整窗口大小时文本重叠导航栏

提交前的验证表单未显示任何验证消息?

如何在锚点可点击的伪元素周围制作空白?

如何计算没有根元素的先前 html 标记(lxml python3)编辑:还获取元素