有没有一种快速的方法可以将 pandas DataFrame 变成漂亮的 HTML 表格?
Posted
技术标签:
【中文标题】有没有一种快速的方法可以将 pandas DataFrame 变成漂亮的 HTML 表格?【英文标题】:Is there a quick way to turn a pandas DataFrame into a pretty HTML table? 【发布时间】:2018-01-07 09:48:56 【问题描述】:问题:df.to_html()
的输出是一个普通的 html 表格,看的不多:
同时,Jupyter Notebook 中数据帧的可视化表示要好得多,但如果有一种简单的方法可以复制它,我还没有找到。
我知道通过摆弄df.style
应该可以生成一个更美观的表格,但是在我开始学习 CSS 之前,有没有人已经编写了一个函数来做到这一点?
【问题讨论】:
这里有一些您可以使用的信息:https://rstudio.github.io/DT/010-style.html @cosinepenguin 我在里面没有看到任何关于熊猫的信息... 自pandas
0.17.1 以来,添加了许多样式选项。查看docs
【参考方案1】:
考虑我的数据框df
df = pd.DataFrame(np.arange(9).reshape(3, 3), list('ABC'), list('XYZ'))
df
X Y Z
A 0 1 2
B 3 4 5
C 6 7 8
我从我的 jupyter 笔记本上撕下了这种风格
my_style = """background-color: rgba(0, 0, 0, 0);
border-bottom-color: rgb(0, 0, 0);
border-bottom-style: none;
border-bottom-width: 0px;
border-collapse: collapse;
border-image-outset: 0px;
border-image-repeat: stretch;
border-image-slice: 100%;
border-image-source: none;
border-image-width: 1;
border-left-color: rgb(0, 0, 0);
border-left-style: none;
border-left-width: 0px;
border-right-color: rgb(0, 0, 0);
border-right-style: none;
border-right-width: 0px;
border-top-color: rgb(0, 0, 0);
border-top-style: none;
border-top-width: 0px;
box-sizing: border-box;
color: rgb(0, 0, 0);
display: table;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 12px;
height: 1675px;
line-height: 20px;
margin-left: 0px;
margin-right: 0px;
margin-top: 12px;
table-layout: fixed;
text-size-adjust: 100%;
width: 700px;
-webkit-border-horizontal-spacing: 0px;
-webkit-border-vertical-spacing: 0px;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"""
我从my post得到这个
def HTML_with_style(df, style=None, random_id=None):
from IPython.display import HTML
import numpy as np
import re
df_html = df.to_html()
if random_id is None:
random_id = 'id%d' % np.random.choice(np.arange(1000000))
if style is None:
style = """
<style>
table#random_id color: blue
</style>
""".format(random_id=random_id)
else:
new_style = []
s = re.sub(r'</?style>', '', style).strip()
for line in s.split('\n'):
line = line.strip()
if not re.match(r'^table', line):
line = re.sub(r'^', 'table ', line)
new_style.append(line)
new_style = ['<style>'] + new_style + ['</style>']
style = re.sub(r'table(#\S+)?', 'table#%s' % random_id, '\n'.join(new_style))
df_html = re.sub(r'<table', r'<table id=%s ' % random_id, df_html)
return HTML(style + df_html)
然后我实现
HTML_with_style(df, '<style>table </style>'.format(my_style))
你可以修改代码来转储html
def HTML_with_style(df, style=None, random_id=None):
import numpy as np
import re
df_html = df.to_html()
if random_id is None:
random_id = 'id%d' % np.random.choice(np.arange(1000000))
if style is None:
style = """
<style>
table#random_id color: blue
</style>
""".format(random_id=random_id)
else:
new_style = []
s = re.sub(r'</?style>', '', style).strip()
for line in s.split('\n'):
line = line.strip()
if not re.match(r'^table', line):
line = re.sub(r'^', 'table ', line)
new_style.append(line)
new_style = ['<style>'] + new_style + ['</style>']
style = re.sub(r'table(#\S+)?', 'table#%s' % random_id, '\n'.join(new_style))
df_html = re.sub(r'<table', r'<table id=%s ' % random_id, df_html)
return style + df_html
现在
HTML_with_style(df, '<style>table </style>'.format(my_style))
'<style>\ntable#id850184 background-color: rgba(0, 0, 0, 0);\ntable#id850184 border-bottom-color: rgb(0, 0, 0);\ntable#id850184 border-bottom-style: none;\ntable#id850184 border-bottom-width: 0px;\ntable#id850184 border-collapse: collapse;\ntable#id850184 border-image-outset: 0px;\ntable#id850184 border-image-repeat: stretch;\ntable#id850184 border-image-slice: 100%;\ntable#id850184 border-image-source: none;\ntable#id850184 border-image-width: 1;\ntable#id850184 border-left-color: rgb(0, 0, 0);\ntable#id850184 border-left-style: none;\ntable#id850184 border-left-width: 0px;\ntable#id850184 border-right-color: rgb(0, 0, 0);\ntable#id850184 border-right-style: none;\ntable#id850184 border-right-width: 0px;\ntable#id850184 border-top-color: rgb(0, 0, 0);\ntable#id850184 border-top-style: none;\ntable#id850184 border-top-width: 0px;\ntable#id850184 box-sizing: border-box;\ntable#id850184 color: rgb(0, 0, 0);\ntable#id850184 display: table#id850184;\ntable#id850184 font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;\ntable#id850184 font-size: 12px;\ntable#id850184 height: 1675px;\ntable#id850184 line-height: 20px;\ntable#id850184 margin-left: 0px;\ntable#id850184 margin-right: 0px;\ntable#id850184 margin-top: 12px;\ntable#id850184-layout: fixed;\ntable#id850184 text-size-adjust: 100%;\ntable#id850184 width: 700px;\ntable#id850184 -webkit-border-horizontal-spacing: 0px;\ntable#id850184 -webkit-border-vertical-spacing: 0px;\ntable#id850184 -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n</style><table id=id850184 border="1" class="dataframe">\n <thead>\n <tr style="text-align: right;">\n <th></th>\n <th>X</th>\n <th>Y</th>\n <th>Z</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>A</th>\n <td>0</td>\n <td>1</td>\n <td>2</td>\n </tr>\n <tr>\n <th>B</th>\n <td>3</td>\n <td>4</td>\n <td>5</td>\n </tr>\n <tr>\n <th>C</th>\n <td>6</td>\n <td>7</td>\n <td>8</td>\n </tr>\n </tbody>\n</table>'
【讨论】:
【参考方案2】:您还可以在笔记本顶部添加以下 Raw NBConvert 单元格:
<link rel="stylesheet" href="https://cdn.jupyter.org/notebook/5.1.0/style/style.min.css">
NBConvert 似乎无法将这些样式添加到导出的 HTML 中。上面的行将显式添加它们。
Source
【讨论】:
【参考方案3】:如果 html 表格的样式确实是这里的问题,我们总是可以使用(众所周知的)css 来获得如下表格:
只需添加一个 id 并将表格样式设置为他们想要的任何方式。
【讨论】:
如何在 Python 中实现这个? 你能提供代码来实现这个吗?【参考方案4】:经过一番研究,我发现最漂亮和最简单的解决方案是https://pypi.org/project/pretty-html-table/
import pandas as pd
from pretty_html_table import build_table
df = pd.DataFrame(np.arange(9).reshape(3, 3), list('ABC'), list('XYZ'))
html_table_blue_light = build_table(df, 'blue_light')
print(html_table_blue_light)
with open('styled_table.html', 'w') as f:
f.write(html_table_blue_light)
【讨论】:
【参考方案5】:<link rel="stylesheet" href="https://cdn.jupyter.org/notebook/5.1.0/style/style.min.css">
你需要将class="rendered_html"
添加到<body>
,否则它将不起作用。
【讨论】:
以上是关于有没有一种快速的方法可以将 pandas DataFrame 变成漂亮的 HTML 表格?的主要内容,如果未能解决你的问题,请参考以下文章
当您的数据不在偶数时间间隔内时,是不是有一种快速方法可以在偶数时间间隔内对 Pandas Dataframe 进行滚动求和?
用pandas_profiling快速探索数据,算不算EDA(Exploratory Data Analysis)首选工具