按行格式化 Pandas 数据帧

12

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

我有如下数据框,希望将其转换为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 文档并尝试了几种方法,但还不能完成上述所有任务。
希望你能给我帮助,因为我认为对于许多 pandas 用户来说,逐行格式化数据框是一个挑战。 编辑 1: 我尝试了以下代码:
df=df.transpose()    
df.style.format("{:.2%}").format({"VAR1":"{:.2f},"VAR4":"{:.2f}"})

注意:通过转置数据框,所有任务都变得更容易,但是我不能将其转置回原始形状,因为它是样式化的。

你到目前为止尝试了什么?如果你有一些代码,任何东西都可以帮助。否则人们可能会建议你已经尝试过的东西。或者他们可以帮助你让它们正常工作。 - Graipher
1
我已经添加了我的一些代码并解释了它的限制。 - Jeff Tehrani
2个回答

6

我认为您可以使用自定义的样式函数来实现您想要的功能:

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>


6

我曾经也遇到过相同的问题,研究了 pandas.io.formats.style.Styler 类中的 format 函数实现,并实现了一个类似的逐行函数:

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

这对我来说可行 :)

注意:

  • 我仅实现了字典格式化器!
  • 格式必须作为函数给出(这里使用lambda)

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接