8

我有以下数据框并想将其转换为 HTML

            Limit        Status     Warning      3M AVG
VAR1        1.20         1.21216    1.11         1.21235
VAR2        0.82         0.63075    0.75         0.593295
VAR3        0.38         0.376988   0.35         0.376988
VAR4        0.17         0.126987   0.14         0.12461

我想按行格式化这个数据框,这样:

  1. 如果Status超过Warning整行变成黄色高亮,如果超过Limit整行变成红色高亮
  2. VAR2VAR3具有“{:.2%}”格式VAR1VAR4具有“{:.2f}”

我已经深入研究了 pandas 文档并尝试了几种方法,但我无法完成上述所有任务

如果您能提供帮助,我将不胜感激,因为我相信对于许多熊猫用户来说,明智地格式化数据框行是一个挑战。

编辑1:我尝试了以下代码:

df=df.transpose()    
df.style.format("{:.2%}").format({"VAR1":"{:.2f},"VAR4":"{:.2f}"})

注意:通过转置数据框,可以更轻松地完成所有任务,但我无法将其转回其原始形状,因为它是样式器。

4

2 回答 2

5

我认为您可以使用自定义样式功能做您想做的事:

def color(row):
    if row.Status >= row.Limit:
        return ['background-color: red'] * len(row)
    elif row.Status >= row.Warning:
        return ['background-color: yellow'] * len(row)
    return [''] * len(row)

df.style.apply(color, axis=1)

在此处输入图像描述

不过,您仍然需要为此添加自定义数字格式。

要为此获取 HTML 代码,请使用以下render方法:

df.style.apply(color, axis=1).render()

<style  type="text/css" >
    #T_e61b55e0_cef5_11e8_9f07_68f72880acdcrow0_col0 {
            background-color:  red;
        }    #T_e61b55e0_cef5_11e8_9f07_68f72880acdcrow0_col1 {
            background-color:  red;
        }    #T_e61b55e0_cef5_11e8_9f07_68f72880acdcrow0_col2 {
            background-color:  red;
        }    #T_e61b55e0_cef5_11e8_9f07_68f72880acdcrow0_col3 {
            background-color:  red;
        }    #T_e61b55e0_cef5_11e8_9f07_68f72880acdcrow2_col0 {
            background-color:  yellow;
        }    #T_e61b55e0_cef5_11e8_9f07_68f72880acdcrow2_col1 {
            background-color:  yellow;
        }    #T_e61b55e0_cef5_11e8_9f07_68f72880acdcrow2_col2 {
            background-color:  yellow;
        }    #T_e61b55e0_cef5_11e8_9f07_68f72880acdcrow2_col3 {
            background-color:  yellow;
        }</style>  
<table id="T_e61b55e0_cef5_11e8_9f07_68f72880acdc" > 
<thead>    <tr> 
        <th class="blank level0" ></th> 
        <th class="col_heading level0 col0" >Limit</th> 
        <th class="col_heading level0 col1" >Status</th> 
        <th class="col_heading level0 col2" >Warning</th> 
        <th class="col_heading level0 col3" >3M AVG</th> 
    </tr></thead> 
<tbody>    <tr> 
        <th id="T_e61b55e0_cef5_11e8_9f07_68f72880acdclevel0_row0" class="row_heading level0 row0" >VAR1</th> 
        <td id="T_e61b55e0_cef5_11e8_9f07_68f72880acdcrow0_col0" class="data row0 col0" >1.2</td> 
        <td id="T_e61b55e0_cef5_11e8_9f07_68f72880acdcrow0_col1" class="data row0 col1" >1.21216</td> 
        <td id="T_e61b55e0_cef5_11e8_9f07_68f72880acdcrow0_col2" class="data row0 col2" >1.11</td> 
        <td id="T_e61b55e0_cef5_11e8_9f07_68f72880acdcrow0_col3" class="data row0 col3" >1.21235</td> 
    </tr>    <tr> 
        <th id="T_e61b55e0_cef5_11e8_9f07_68f72880acdclevel0_row1" class="row_heading level0 row1" >VAR2</th> 
        <td id="T_e61b55e0_cef5_11e8_9f07_68f72880acdcrow1_col0" class="data row1 col0" >0.82</td> 
        <td id="T_e61b55e0_cef5_11e8_9f07_68f72880acdcrow1_col1" class="data row1 col1" >0.63075</td> 
        <td id="T_e61b55e0_cef5_11e8_9f07_68f72880acdcrow1_col2" class="data row1 col2" >0.75</td> 
        <td id="T_e61b55e0_cef5_11e8_9f07_68f72880acdcrow1_col3" class="data row1 col3" >0.593295</td> 
    </tr>    <tr> 
        <th id="T_e61b55e0_cef5_11e8_9f07_68f72880acdclevel0_row2" class="row_heading level0 row2" >VAR3</th> 
        <td id="T_e61b55e0_cef5_11e8_9f07_68f72880acdcrow2_col0" class="data row2 col0" >0.38</td> 
        <td id="T_e61b55e0_cef5_11e8_9f07_68f72880acdcrow2_col1" class="data row2 col1" >0.376988</td> 
        <td id="T_e61b55e0_cef5_11e8_9f07_68f72880acdcrow2_col2" class="data row2 col2" >0.35</td> 
        <td id="T_e61b55e0_cef5_11e8_9f07_68f72880acdcrow2_col3" class="data row2 col3" >0.376988</td> 
    </tr>    <tr> 
        <th id="T_e61b55e0_cef5_11e8_9f07_68f72880acdclevel0_row3" class="row_heading level0 row3" >VAR4</th> 
        <td id="T_e61b55e0_cef5_11e8_9f07_68f72880acdcrow3_col0" class="data row3 col0" >0.17</td> 
        <td id="T_e61b55e0_cef5_11e8_9f07_68f72880acdcrow3_col1" class="data row3 col1" >0.126987</td> 
        <td id="T_e61b55e0_cef5_11e8_9f07_68f72880acdcrow3_col2" class="data row3 col2" >0.14</td> 
        <td id="T_e61b55e0_cef5_11e8_9f07_68f72880acdcrow3_col3" class="data row3 col3" >0.12461</td> 
    </tr></tbody> 
</table>

于 2018-10-12T16:41:21.503 回答
4

我遇到了同样的问题,并研究了类中format函数的pandas.io.formats.style.Styler实现并实现了类似的逐行函数:

def format_row_wise(styler, formatter):
    for row, row_formatter in formatter.items():
        row_num = styler.index.get_loc(row)

        for col_num in range(len(styler.columns)):
            styler._display_funcs[(row_num, col_num)] = row_formatter
    return styler

示例

df = pandas.DataFrame(
    {
        'Limit': [1.20, 0.82, 0.38, 0.17], 
        'Status': [1.21216, 0.63075, 0.376988, 0.126987], 
        'Warning': [1.11, 0.75, 0.35, 0.14], 
        '3M AVG': [1.21235, 0.593259, 0.376988, 0.12461]
    }, 
    index=['VAR1', 'VAR2', 'VAR3', 'VAR4']
)
formatters = {"VAR1":lambda x: f"{x:.2f}", "VAR4": lambda x: f"{x:.2f}"}
styler = format_row_wise(df.style, formatters)
styler.render()

这对我有用:)

注意

  • 我只实现了dict-formatter!
  • 格式必须作为函数给出(这里:lambda)

希望这能让你走上正确的道路......

于 2019-01-30T15:56:14.467 回答