【问题标题】:Replicating Jupyter Notebook Pandas dataframe HTML printout复制 Jupyter Notebook Pandas 数据框 HTML 打印输出
【发布时间】:2018-08-25 17:55:10
【问题描述】:

我正在尝试将 jupyter 在其笔记本中用于 pandas 数据框的输出复制到 html/css/js,以便 Flask jsonify 可以将其作为 html 返回,以便我稍后在 AJAX 调用中使用。

我找到了 thisthis,它们建议使用 pandas 内置样式功能而不是 CSS hack,但我正在努力获得所需的功能:

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

与 jupyter 笔记本相比,这缺少一些默认的背景颜色剥离,并且标题不应应用悬停类。我能想到在选择元素上应用某些东西的唯一方法是添加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> 

【问题讨论】:

    标签: python css pandas jupyter-notebook


    【解决方案1】:

    我确实花了一些时间来寻找模板在哪里,但在这里,link

    我相信这包括笔记本单元格输出的所有 CSS,因此您只需要与表格相关的部分(表格、thead、tbody、th 等)并根据自己的喜好调整它们。你仍然需要在 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>

    【讨论】:

    • 看起来您忘记提及您在 .less 文件中用 black 替换了 @rendered_html_border_color。现在我可以粘贴相关的摘录,进行替换,效果很好。谢谢!
    【解决方案2】:

    我对您的代码进行了一些更改以获得您想要的功能:

    • Pandas 数据帧使用两个特殊的 HTML 标签用于表格样式,即thead 用于标题,tbody 用于正文。我们可以使用它来将突出显示行为指定为仅正文
    • CSS 具有“偶数”和“奇数”属性,您可以使用它们为表格添加阴影效果。
    • 为了使悬停与指定的背景阴影一起工作,必须最后而不是首先调用它

    在 Jupyter Notebook 中:

    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
    

    ...但是当我们输出HTML文件时它仍然很漂亮吗?? 是的。你可以做更多的 CSS 样式来让它恰到好处(字体大小、字体系列、文本装饰、边距/填充等),但这给了你一个开始。见下文:

    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> 

    【讨论】:

    • 非常感谢,这正是我想要的。
    猜你喜欢
    • 2018-09-28
    • 1970-01-01
    • 2017-11-25
    • 2019-04-22
    • 2019-12-25
    • 1970-01-01
    • 1970-01-01
    • 2021-03-03
    • 2020-05-21
    相关资源
    最近更新 更多