首页 > 解决方案 > 如何以数据框样式添加文本或标签以显示信息

问题描述

我有以下样式来显示两个数据框的差异,另外我如何使用数据框/熊猫样式显示记录总数和不匹配行数?

       def highlight_diff(data, color='yellow'):
            attr = 'background-color: {}'.format(color)
            other = data.xs('First', axis='columns', level=-1)
            return pd.DataFrame(np.where(data.ne(other, level=0), attr, ''),
                                index=data.index, columns=data.columns)
        caption_styles = {
            'selector':'caption',
            'props':[('font-weight', 'bold'),('margin-bottom','25px'),('font-size','25px')]
        }
        select_styles = {  # for row hover use <tr> instead of <td>
            'selector': '',
            'props': [('border-collapse', 'collapse'),('margin', '100px auto')]
        }
        
        table_styles = {  # for row hover use <tr> instead of <td>
            'selector': 'table',
            'props': [('border-collapse', 'collapse'),('margin', '100px auto')]
        }
        
        tbody_styles = {  # for row hover use <tr> instead of <td>
            'selector': 'tbody',
            'props': [('border', '1px solid #A2DBFA')]
        }
        td_styles = {  # for row hover use <tr> instead of <td>
            'selector': 'td',
            'props': [('border', '1px solid #A2DBFA'),('padding','1em'),('border-bottom','2px solid #A2DBFA')]
        }
        th_styles = {  # for row hover use <tr> instead of <td>
            'selector': 'th',
            'props': [('border', '1px solid #A2DBFA'),('padding','1em'),('background-color','#39A2DB'),('border-bottom','2px solid #A2DBFA')]
        }
df_all = pd.concat([df_source.set_index('id'), df_target.set_index('id')], 
                   axis='columns', keys=['First', 'Second']).drop_duplicates(keep=False)
df_final = df_all.swaplevel(axis='columns')[df_source.columns[1:]]
        df_out = df_final.style.set_table_styles([caption_styles,select_styles,table_styles, tbody_styles,td_styles, th_styles]).set_caption("Test Case 1").apply(highlight_diff, axis=None)

一旦我拥有所有数据,我将使用 Html 进行渲染df.render()并将其编写为 Html。我想使用 pandas/dataframe 样式显示记录总数和不匹配行数(红色文本中提到)

在此处输入图像描述

标签: pythonpandasnumpy

解决方案


你可以

a)(最简单)将信息合并到标题中,并插入计算值:

df = pd.DataFrame(index=pd.MultiIndex.from_product([["Unit 1", "Unit 2"], ["Some Value", "Another"]], names=["Dept", "Workflow"]),
                  columns=["Comment 1", "Comment 2"],
                  data=[["Green", "Red"], ["Yellow", "Yellow"], ["Green", "Red"], ["Yellow", "Yellow"]])
styler = df.style
styler.set_table_styles([{'selector': 'td', 'props': 'text-align: left;'},
                         {'selector': 'th.level1', 'props': 'text-align: left;'},
                         {'selector': 'caption', 'props': 'color: red;'}])\
      .applymap(lambda x: f"color: {x.lower()}")\
      .set_caption(f"number of reds: {2}<br>number of rows: {4}")

在此处输入图像描述

由于标题直接从字符串呈现为 HTML,因此您实际上可以很聪明并使用标题来构建多个元素。例如:

styler.set_table_styles([{'selector': 'td', 'props': 'text-align: left;'},
                         {'selector': 'th.level1', 'props': 'text-align: left;'},
                         {'selector': 'caption', 'props': 'color: red;'},
                         {'selector': '.my-cls', 'props': 'color: blue; font-size: 16pt;'])\
      .applymap(lambda x: f"color: {x.lower()}")\
      .set_caption('<span class="my-cls">Big Blue Text</span><br>little red text')

在此处输入图像描述

b)(更难)按照用户指南中的说明对样式器模板进行子类化

在与笔记本相同的目录中创建一个新文件“my_html.tpl”,如下所示:

{% extends "html_table.tpl" %}
{% block table %}
<h1>{{ table_title|default("My Table") }}</h1>
<p style="color: red; font-size: 1.5em;">number of reds: {{ reds }}<br>number of rows: {{ rows }}</p>
{{ super() }}
{% endblock table %}

然后创建自己的Styler

from pandas.io.formats.style import Styler
MyStyler = Styler.from_custom_template(searchpath="", html_table="my_table.tpl")
styler = MyStyler(df)
styler.set_table_styles([{'selector': 'td', 'props': 'text-align: left;'},
                         {'selector': 'th.level1', 'props': 'text-align: left;'}])\
      .applymap(lambda x: f"color: {x.lower()}")\
      .render(reds=2, rows=4)

在此处输入图像描述


推荐阅读