如何扩展 Pandas 基础 Styler 模板

How to extend Pandas base Styler template

你好,我正在编写一个继承自 Pandas 基本模板的自定义神社模板。

我的默认模板看起来像

{% extends "html.tpl" %}
{% block table %}
<style  type="text/css" >
{% block default_table_styles %}
         #T_{{uuid}} th {
          font-size: 100%;
          text-align: center;
          background-color: blue;
          color: white;
          border: black solid thin;
    }    #T_{{uuid}} td {
          font-size: 100%;
          text-align: center;
          background-color: white;
          color: black;
          border: black solid thin;
    }    #T_{{uuid}} th:empty {
          border-width: 0;
    }
{% endblock default_table_styles %}
</style>
{{ super() }}
{% endblock table %}

现在我创建了一个模拟数据框并尝试使用我的自定义模板进行渲染,但效果没有发生。

我的数据框模拟代码

import numpy as np
import pandas as pd
from pandas.io.formats.style import Styler
from IPython.display import HTML
from bs4 import BeautifulSoup as bs
# make complex dataframe
def mklbl(prefix, n):
        return ["%s%s" % (prefix, i) for i in range(n)]
micolumns = pd.MultiIndex.from_tuples([('a', 'foo'), ('a', 'bar'),
                                           ('b', 'foo'), ('b', 'bah')],
                                          names=['lvl0', 'lvl1'])
miindex = pd.MultiIndex.from_product([mklbl('A', 4),
                                      mklbl('B', 2),
                                      mklbl('C', 4),
                                      mklbl('D', 2)], names=['lvl2','lvl3','lvl4','lvl5'])
df = pd.DataFrame(np.arange(len(miindex) * len(micolumns))
                          .reshape((len(miindex), len(micolumns))),
                        index=miindex,
                        columns=micolumns).sort_index().sort_index(axis=1)
df

使用 Pandas 子类工厂函数制作我的自定义子类 Styler object。

EasyStyler = Styler.from_custom_template("path_to_new_tpl_file", "default.tpl")

现在我渲染

EasyStyler(df)

根据我的研究,这应该行得通,但似乎行不通。

我试着漂亮地打印 html,但它看起来根本不像我的样式块。

print(bs(EasyStyler(df).render()).prettify())

我希望用户能够选择覆盖我的默认模板的属性。我的想法是,如果我在他们的任何代码之前包含我的样式块,那么如果用户决定覆盖某些样式属性,那么它们将在稍后出现时优先于我的。

编辑:

所以我能够通过将 style 容器移动到 table 块内来获得我想要的东西。但是,我现在无法覆盖这些设置。

s = EasyStyler(df)
s.set_table_styles(dict(selector="th", props=[('background-color','red'),('color','white')]))

我希望上面的内容会改变 th header 中的背景颜色,但事实并非如此。我很想知道如何让它工作。

编辑2:

所以似乎 parent 模板 style 容器被放置在 child 之前,导致 child 覆盖 parent秒。有没有办法强迫他们换一种方式?

所以在大量阅读之后我发现了问题。

我学到了两件事,因为我之前从未使用过 css/html,更不用说 jinja2 模板了。

如果您查看 Pandas 提供的模板,如果您在子模板中调用继承自它,你放在这些块中的代码会在那个地方执行。

我犯的第二个错误是当我试图将 css 应用于 table 时。我没有意识到,因为 table 是最多的元素,所以我只需要 table id 而不是实际的单词 table.

这两项调整完全满足了我的要求,并且模板仍然可以从 pandas.io.formats.style.Style 子类中完全覆盖。

{% extends "html.tpl" %}
{%- block before_style -%}
<style  type="text/css">
         #T_{{uuid}} th {
          font-size: 100%;
          text-align: center;
          background-color: blue;
          color: white;
          border: black solid thin;
    }    #T_{{uuid}} td {
          font-size: 100%;
          text-align: center;
          background-color: white;
          color: black;
          border: black solid thin;
    }    #T_{{uuid}} th:empty {
          border-width: 0;
    }
</style>
{%- endblock before_style -%}
{%- block before_table -%}
<style>
         #T_{{uuid}} {
          border: black solid thin;
    }
</style>
{%- endblock before_table -%}
{% block table %}
{{ super() }}
{% endblock table %}