简体   繁体   English

复制 Jupyter Notebook Pandas 数据帧 HTML 打印输出

[英]Replicating Jupyter Notebook Pandas dataframe HTML printout

I'm trying to replicate the output that jupyter uses for a pandas dataframe in their notebooks to html/css/js so that it's returnable by Flask jsonify as html that I later use in an AJAX call.我正在尝试将 jupyter 在其笔记本中用于 Pandas 数据框的输出复制到 html/css/js,以便 Flask jsonify可以将其jsonify为 html,稍后我将在 AJAX 调用中使用它。

I found this , and this , which suggested using the pandas builtin style functionality rather than CSS hacks but i'm struggling to get the desired functionality:我发现了thisthis ,它建议使用 pandas 内置样式功能而不是 CSS hacks,但我正在努力获得所需的功能:

def hover(hover_color="#add8e6"):
    return dict(selector="tr:hover",
                props=[("background-color", "%s" % hover_color)])

styles = [
    hover(),
    dict(selector="th", props=[("font-size", "125%"),
                               ("text-align", "center"),
                               ("padding", "5px 5px")]),
    dict(selector="tr", props=[("text-align", "center")]),
    dict(selector="caption", props=[("caption-side", "bottom")])
]

# creating some dummy data
index = pd.MultiIndex(levels=[['bar', 'baz', 'foo', 'qux'], ['one', 'two']],
                      labels=[[0, 0, 1, 1, 2, 2, 3, 3], [0, 1, 0, 1, 0, 1, 0, 1]],
                      names=['first', 'second'])

df = pd.DataFrame(data=np.random.randn(8), index=index)

# you'll see the html rendered bellow
df.style.set_table_styles(styles).set_caption("test").render()

Compared to jupyter notebooks, this is missing some default background color stripping, and the header shouldn't apply the hover class.与 jupyter notebooks 相比,这缺少一些默认的背景颜色剥离,并且标题不应应用悬停类。 The only way I can think to apply something on select elements would be to add class= or id= but the style functionality hides all that.我认为在选择元素上应用某些东西的唯一方法是添加class=id=但样式功能隐藏了所有这些。

 <style type="text/css" > #T_479b61ba_292a_11e8_86bf_0ee09a5428a2 tr:hover { background-color: #add8e6; } #T_479b61ba_292a_11e8_86bf_0ee09a5428a2 th { font-size: 150%; text-align: center; } #T_479b61ba_292a_11e8_86bf_0ee09a5428a2 caption { caption-side: bottom; }</style> <table id="T_479b61ba_292a_11e8_86bf_0ee09a5428a2" ><caption>Hover to highlight.</caption> <thead> <tr> <th class="blank" ></th> <th class="blank level0" ></th> <th class="col_heading level0 col0" >0</th> </tr> <tr> <th class="index_name level0" >first</th> <th class="index_name level1" >second</th> <th class="blank" ></th> </tr></thead> <tbody> <tr> <th id="T_479b61ba_292a_11e8_86bf_0ee09a5428a2level0_row0" class="row_heading level0 row0" rowspan=2>bar</th> <th id="T_479b61ba_292a_11e8_86bf_0ee09a5428a2level1_row0" class="row_heading level1 row0" >one</th> <td id="T_479b61ba_292a_11e8_86bf_0ee09a5428a2row0_col0" class="data row0 col0" >-0.0690895</td> </tr> <tr> <th id="T_479b61ba_292a_11e8_86bf_0ee09a5428a2level1_row1" class="row_heading level1 row1" >two</th> <td id="T_479b61ba_292a_11e8_86bf_0ee09a5428a2row1_col0" class="data row1 col0" >-0.518092</td> </tr> <tr> <th id="T_479b61ba_292a_11e8_86bf_0ee09a5428a2level0_row2" class="row_heading level0 row2" rowspan=2>baz</th> <th id="T_479b61ba_292a_11e8_86bf_0ee09a5428a2level1_row2" class="row_heading level1 row2" >one</th> <td id="T_479b61ba_292a_11e8_86bf_0ee09a5428a2row2_col0" class="data row2 col0" >-0.163842</td> </tr> <tr> <th id="T_479b61ba_292a_11e8_86bf_0ee09a5428a2level1_row3" class="row_heading level1 row3" >two</th> <td id="T_479b61ba_292a_11e8_86bf_0ee09a5428a2row3_col0" class="data row3 col0" >-0.144757</td> </tr> <tr> <th id="T_479b61ba_292a_11e8_86bf_0ee09a5428a2level0_row4" class="row_heading level0 row4" rowspan=2>foo</th> <th id="T_479b61ba_292a_11e8_86bf_0ee09a5428a2level1_row4" class="row_heading level1 row4" >one</th> <td id="T_479b61ba_292a_11e8_86bf_0ee09a5428a2row4_col0" class="data row4 col0" >1.22865</td> </tr> <tr> <th id="T_479b61ba_292a_11e8_86bf_0ee09a5428a2level1_row5" class="row_heading level1 row5" >two</th> <td id="T_479b61ba_292a_11e8_86bf_0ee09a5428a2row5_col0" class="data row5 col0" >1.83947</td> </tr> <tr> <th id="T_479b61ba_292a_11e8_86bf_0ee09a5428a2level0_row6" class="row_heading level0 row6" rowspan=2>qux</th> <th id="T_479b61ba_292a_11e8_86bf_0ee09a5428a2level1_row6" class="row_heading level1 row6" >one</th> <td id="T_479b61ba_292a_11e8_86bf_0ee09a5428a2row6_col0" class="data row6 col0" >0.793328</td> </tr> <tr> <th id="T_479b61ba_292a_11e8_86bf_0ee09a5428a2level1_row7" class="row_heading level1 row7" >two</th> <td id="T_479b61ba_292a_11e8_86bf_0ee09a5428a2row7_col0" class="data row7 col0" >-0.723836</td> </tr></tbody> </table>

I've made a few changes to your code to get the functionality you want:我对您的代码进行了一些更改以获得您想要的功能:

  • Pandas dataframes are styled with two special HTML tags for tables, namely thead for the header and tbody for the body. Pandas 数据框的样式使用两个特殊的 HTML 表格标签,即标题的thead和正文的tbody We can use this to specify the highlighting behavior as body-only我们可以使用它来将高亮行为指定为仅正文
  • CSS has "even" and "odd" properties which you can use to add shading effects to tables. CSS 具有“偶数”和“奇数”属性,您可以使用它们为表格添加阴影效果。
  • In order for hover to work with the background shading specified, it must be called last not first为了使悬停与指定的背景阴影一起工作,它必须在最后而不是第一个调用

In Jupyter Notebook:在 Jupyter 笔记本中:

import pandas as pd
import numpy as np
from IPython.display import HTML

def hover(hover_color="#add8e6"):
    return dict(selector="tbody tr:hover",
            props=[("background-color", "%s" % hover_color)])

styles = [
    #table properties
    dict(selector=" ", 
         props=[("margin","0"),
                ("font-family",'"Helvetica", "Arial", sans-serif'),
                ("border-collapse", "collapse"),
                ("border","none"),
                ("border", "2px solid #ccf")
                   ]),

    #header color - optional
    dict(selector="thead", 
         props=[("background-color","#cc8484")
               ]),

    #background shading
    dict(selector="tbody tr:nth-child(even)",
         props=[("background-color", "#fff")]),
    dict(selector="tbody tr:nth-child(odd)",
         props=[("background-color", "#eee")]),

    #cell spacing
    dict(selector="td", 
         props=[("padding", ".5em")]),

    #header cell properties
    dict(selector="th", 
         props=[("font-size", "125%"),
                ("text-align", "center")]),

    #caption placement
    dict(selector="caption", 
         props=[("caption-side", "bottom")]),

    #render hover last to override background-color
    hover()
]
html = (df.style.set_table_styles(styles)
      .set_caption("Hover to highlight."))
html

Jupyter 输出

...but is it still beautiful when we output the HTML file?? ...但是当我们输出HTML文件时它仍然很漂亮吗?? Yes.是的。 You can do some more CSS styling to get it just right (font-size, font-family, text-decoration, margin/padding, etc) but this gives you a start.你可以做一些更多的 CSS 样式来让它恰到好处(字体大小、字体系列、文本装饰、边距/填充等),但这给了你一个开始。 See below:见下文:

print(html.render())

 <style type="text/css" > #T_3e73cfd2_396c_11e8_9d70_240a645b34fc { margin: 0; font-family: "Helvetica", "Arial", sans-serif; border-collapse: collapse; border: none; border: 2px solid #ccf; } #T_3e73cfd2_396c_11e8_9d70_240a645b34fc thead { background-color: #cc8484; } #T_3e73cfd2_396c_11e8_9d70_240a645b34fc tbody tr:nth-child(even) { background-color: #fff; } #T_3e73cfd2_396c_11e8_9d70_240a645b34fc tbody tr:nth-child(odd) { background-color: #eee; } #T_3e73cfd2_396c_11e8_9d70_240a645b34fc td { padding: .5em; } #T_3e73cfd2_396c_11e8_9d70_240a645b34fc th { font-size: 125%; text-align: center; } #T_3e73cfd2_396c_11e8_9d70_240a645b34fc caption { caption-side: bottom; } #T_3e73cfd2_396c_11e8_9d70_240a645b34fc tbody tr:hover { background-color: #add8e6; }</style> <table id="T_3e73cfd2_396c_11e8_9d70_240a645b34fc" ><caption>Hover to highlight.</caption> <thead> <tr> <th class="blank" ></th> <th class="blank level0" ></th> <th class="col_heading level0 col0" >0</th> </tr> <tr> <th class="index_name level0" >first</th> <th class="index_name level1" >second</th> <th class="blank" ></th> </tr></thead> <tbody> <tr> <th id="T_3e73cfd2_396c_11e8_9d70_240a645b34fclevel0_row0" class="row_heading level0 row0" rowspan=2>bar</th> <th id="T_3e73cfd2_396c_11e8_9d70_240a645b34fclevel1_row0" class="row_heading level1 row0" >one</th> <td id="T_3e73cfd2_396c_11e8_9d70_240a645b34fcrow0_col0" class="data row0 col0" >-0.130634</td> </tr> <tr> <th id="T_3e73cfd2_396c_11e8_9d70_240a645b34fclevel1_row1" class="row_heading level1 row1" >two</th> <td id="T_3e73cfd2_396c_11e8_9d70_240a645b34fcrow1_col0" class="data row1 col0" >1.17685</td> </tr> <tr> <th id="T_3e73cfd2_396c_11e8_9d70_240a645b34fclevel0_row2" class="row_heading level0 row2" rowspan=2>baz</th> <th id="T_3e73cfd2_396c_11e8_9d70_240a645b34fclevel1_row2" class="row_heading level1 row2" >one</th> <td id="T_3e73cfd2_396c_11e8_9d70_240a645b34fcrow2_col0" class="data row2 col0" >0.500367</td> </tr> <tr> <th id="T_3e73cfd2_396c_11e8_9d70_240a645b34fclevel1_row3" class="row_heading level1 row3" >two</th> <td id="T_3e73cfd2_396c_11e8_9d70_240a645b34fcrow3_col0" class="data row3 col0" >0.555932</td> </tr> <tr> <th id="T_3e73cfd2_396c_11e8_9d70_240a645b34fclevel0_row4" class="row_heading level0 row4" rowspan=2>foo</th> <th id="T_3e73cfd2_396c_11e8_9d70_240a645b34fclevel1_row4" class="row_heading level1 row4" >one</th> <td id="T_3e73cfd2_396c_11e8_9d70_240a645b34fcrow4_col0" class="data row4 col0" >-0.744553</td> </tr> <tr> <th id="T_3e73cfd2_396c_11e8_9d70_240a645b34fclevel1_row5" class="row_heading level1 row5" >two</th> <td id="T_3e73cfd2_396c_11e8_9d70_240a645b34fcrow5_col0" class="data row5 col0" >-1.41269</td> </tr> <tr> <th id="T_3e73cfd2_396c_11e8_9d70_240a645b34fclevel0_row6" class="row_heading level0 row6" rowspan=2>qux</th> <th id="T_3e73cfd2_396c_11e8_9d70_240a645b34fclevel1_row6" class="row_heading level1 row6" >one</th> <td id="T_3e73cfd2_396c_11e8_9d70_240a645b34fcrow6_col0" class="data row6 col0" >0.726728</td> </tr> <tr> <th id="T_3e73cfd2_396c_11e8_9d70_240a645b34fclevel1_row7" class="row_heading level1 row7" >two</th> <td id="T_3e73cfd2_396c_11e8_9d70_240a645b34fcrow7_col0" class="data row7 col0" >-0.683555</td> </tr></tbody> </table>

Definitely took me a while to look for where the template is, but here it is, link .我肯定花了一段时间来寻找模板的位置,但在这里, 链接

I believe this includes all the CSS for notebook cell outputs, so you just need the table related parts (table, thead, tbody, th, etc) and tweak them to your liking.我相信这包括笔记本单元格输出的所有 CSS,因此您只需要与表格相关的部分(表格、thead、tbody、th 等)并根据自己的喜好调整它们。 You still need to turn it in python, but to illustrate it works, here's the raw HTML你仍然需要在 python 中打开它,但为了说明它的工作原理,这里是原始 HTML

 <style type="text/css" > table { border: none; border-collapse: collapse; border-spacing: 0; color: black; font-size: 12px; table-layout: fixed; } thead { border-bottom: 1px solid black; vertical-align: bottom; } tr, th, td { text-align: right; vertical-align: middle; padding: 0.5em 0.5em; line-height: normal; white-space: normal; max-width: none; border: none; } th { font-weight: bold; } tbody tr:nth-child(odd) { background: #f5f5f5; } tbody tr:hover { background: rgba(66, 165, 245, 0.2); } </style><table id="T_32dd1d4a_f245_11ea_977b_005056813a0d" ><thead> <tr> <th class="blank" ></th> <th class="blank level0" ></th> <th class="col_heading level0 col0" >0</th> </tr> <tr> <th class="index_name level0" >first</th> <th class="index_name level1" >second</th> <th class="blank" ></th> </tr></thead><tbody> <tr> <th id="T_32dd1d4a_f245_11ea_977b_005056813a0dlevel0_row0" class="row_heading level0 row0" rowspan=2>bar</th> <th id="T_32dd1d4a_f245_11ea_977b_005056813a0dlevel1_row0" class="row_heading level1 row0" >one</th> <td id="T_32dd1d4a_f245_11ea_977b_005056813a0drow0_col0" class="data row0 col0" >-0.466253</td> </tr> <tr> <th id="T_32dd1d4a_f245_11ea_977b_005056813a0dlevel1_row1" class="row_heading level1 row1" >two</th> <td id="T_32dd1d4a_f245_11ea_977b_005056813a0drow1_col0" class="data row1 col0" >-0.579658</td> </tr> <tr> <th id="T_32dd1d4a_f245_11ea_977b_005056813a0dlevel0_row2" class="row_heading level0 row2" rowspan=2>baz</th> <th id="T_32dd1d4a_f245_11ea_977b_005056813a0dlevel1_row2" class="row_heading level1 row2" >one</th> <td id="T_32dd1d4a_f245_11ea_977b_005056813a0drow2_col0" class="data row2 col0" >1.868159</td> </tr> <tr> <th id="T_32dd1d4a_f245_11ea_977b_005056813a0dlevel1_row3" class="row_heading level1 row3" >two</th> <td id="T_32dd1d4a_f245_11ea_977b_005056813a0drow3_col0" class="data row3 col0" >0.392282</td> </tr> <tr> <th id="T_32dd1d4a_f245_11ea_977b_005056813a0dlevel0_row4" class="row_heading level0 row4" rowspan=2>foo</th> <th id="T_32dd1d4a_f245_11ea_977b_005056813a0dlevel1_row4" class="row_heading level1 row4" >one</th> <td id="T_32dd1d4a_f245_11ea_977b_005056813a0drow4_col0" class="data row4 col0" >-2.427858</td> </tr> <tr> <th id="T_32dd1d4a_f245_11ea_977b_005056813a0dlevel1_row5" class="row_heading level1 row5" >two</th> <td id="T_32dd1d4a_f245_11ea_977b_005056813a0drow5_col0" class="data row5 col0" >-0.813941</td> </tr> <tr> <th id="T_32dd1d4a_f245_11ea_977b_005056813a0dlevel0_row6" class="row_heading level0 row6" rowspan=2>qux</th> <th id="T_32dd1d4a_f245_11ea_977b_005056813a0dlevel1_row6" class="row_heading level1 row6" >one</th> <td id="T_32dd1d4a_f245_11ea_977b_005056813a0drow6_col0" class="data row6 col0" >0.110564</td> </tr> <tr> <th id="T_32dd1d4a_f245_11ea_977b_005056813a0dlevel1_row7" class="row_heading level1 row7" >two</th> <td id="T_32dd1d4a_f245_11ea_977b_005056813a0drow7_col0" class="data row7 col0" >0.834701</td> </tr> </tbody></table>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM