逐行格式化熊猫数据框
Posted
技术标签:
【中文标题】逐行格式化熊猫数据框【英文标题】:Format pandas dataframe row wise 【发布时间】:2019-03-17 21:57:25 【问题描述】:我有以下数据框并想将其转换为 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
我想按行格式化这个数据框:
-
如果
Status
超过Warning
,整行变为黄色突出显示,如果超过Limit
,整行变为红色突出显示
VAR2
和VAR3
行的格式为“:.2%”,VAR1
和VAR4
的格式为“:.2f”
我研究了 pandas 文档并尝试了几种方法,但我无法完成上述所有任务
如果您能提供帮助,我将不胜感激,因为我相信对许多 pandas 用户来说,明智地格式化数据框行是一个挑战。
编辑1:我试过以下代码:
df=df.transpose()
df.style.format(":.2%").format("VAR1":":.2f,"VAR4":":.2f")
注意:通过转置数据框可以更轻松地完成所有任务,但我无法将其转回原来的形状,因为它是样式器。
【问题讨论】:
到目前为止,您到底尝试了什么?如果你有一些代码,任何东西都可以提供帮助。否则人们可能只会推荐你已经尝试过的东西。或者他们可以帮助您让他们工作。 我已经添加了我的一些代码并解释了它的局限性 【参考方案1】:我认为您可以使用自定义 Styling 函数做您想做的事:
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>
【讨论】:
【参考方案2】:我遇到了同样的问题,并查看了 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()
这对我有用:)
注意:
我只实现了 dict-formatter! 格式必须作为函数给出(这里:lambda)希望这能让你走上正确的道路......
【讨论】:
以上是关于逐行格式化熊猫数据框的主要内容,如果未能解决你的问题,请参考以下文章