Jupyter 笔记本并排显示两个 Pandas 表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/38783027/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Jupyter notebook display two pandas tables side by side
提问by Salvador Dali
I have two pandas dataframes and I would like to display them in Jupyter notebook.
我有两个熊猫数据框,我想在 Jupyter 笔记本中显示它们。
Doing something like:
做类似的事情:
display(df1)
display(df2)
Shows them one below another:
显示它们一个在另一个下面:
I would like to have a second dataframe on the right of the first one. There is a similar question, but it looks like there a person is satisfied either with merging them in one dataframe of showing the difference between them.
我想在第一个数据框的右侧有第二个数据框。有一个类似的问题,但看起来有人对将它们合并在一个显示它们之间差异的数据框中感到满意。
This will not work for me. In my case dataframes can represent completely different (non-comparable elements) and the size of them can be different. Thus my main goal is to save space.
这对我不起作用。在我的情况下,数据框可以表示完全不同的(不可比较的元素)并且它们的大小可以不同。因此,我的主要目标是节省空间。
采纳答案by zarak
You could override the CSS of the output code. It uses flex-direction: column
by default. Try changing it to row
instead. Here's an example:
您可以覆盖输出代码的 CSS。它flex-direction: column
默认使用。尝试将其更改为row
。下面是一个例子:
import pandas as pd
import numpy as np
from IPython.display import display, HTML
CSS = """
.output {
flex-direction: row;
}
"""
HTML('<style>{}</style>'.format(CSS))
You could, of course, customize the CSS further as you wish.
当然,您可以根据需要进一步自定义 CSS。
If you wish to target only one cell's output, try using the :nth-child()
selector. For example, this code will modify the CSS of the output of only the 5th cell in the notebook:
如果您希望只针对一个单元格的输出,请尝试使用:nth-child()
选择器。例如,此代码将修改笔记本中仅第 5 个单元格的输出的 CSS:
CSS = """
div.cell:nth-child(5) .output {
flex-direction: row;
}
"""
回答by ntg
I have ended up writing a function that can do this:
我最终编写了一个可以执行此操作的函数:
from IPython.display import display_html
def display_side_by_side(*args):
html_str=''
for df in args:
html_str+=df.to_html()
display_html(html_str.replace('table','table style="display:inline"'),raw=True)
Example usage:
用法示例:
df1 = pd.DataFrame(np.arange(12).reshape((3,4)),columns=['A','B','C','D',])
df2 = pd.DataFrame(np.arange(16).reshape((4,4)),columns=['A','B','C','D',])
display_side_by_side(df1,df2,df1)
回答by gibbone
Starting from pandas 0.17.1
the visualization of DataFrames can be directly modified with pandas styling methods
从pandas 0.17.1
DataFrame的可视化入手,可以直接用pandas的样式方法修改
To display two DataFrames side by side you must use set_table_attributes
with the argument "style='display:inline'"
as suggested in ntg answer. This will return two Styler
objects. To display the aligned dataframes just pass their joined HTML representation through the display_html
method from IPython.
要并排显示两个 DataFrame,您必须使用ntg answer 中建议set_table_attributes
的参数。这将返回两个对象。要显示对齐的数据框,只需通过IPython的方法传递它们连接的 HTML 表示。"style='display:inline'"
Styler
display_html
With this method is also easier to add other styling options. Here's how to add a caption, as requested here:
使用此方法还可以更轻松地添加其他样式选项。以下是根据此处的要求添加标题的方法:
import numpy as np
import pandas as pd
from IPython.display import display_html
df1 = pd.DataFrame(np.arange(12).reshape((3,4)),columns=['A','B','C','D',])
df2 = pd.DataFrame(np.arange(16).reshape((4,4)),columns=['A','B','C','D',])
df1_styler = df1.style.set_table_attributes("style='display:inline'").set_caption('Caption table 1')
df2_styler = df2.style.set_table_attributes("style='display:inline'").set_caption('Caption table 2')
display_html(df1_styler._repr_html_()+df2_styler._repr_html_(), raw=True)
回答by Anton Golubev
Combining approaches of gibbone (to set styles and captions) and stevi (adding space) I made my version of function, which outputs pandas dataframes as tables side-by-side:
结合 gibbone(设置样式和标题)和 stevi(添加空间)的方法,我制作了我的函数版本,它将 Pandas 数据框并排输出为表格:
from IPython.core.display import display, HTML
def display_side_by_side(dfs:list, captions:list):
"""Display tables side by side to save vertical space
Input:
dfs: list of pandas.DataFrame
captions: list of table captions
"""
output = ""
combined = dict(zip(captions, dfs))
for caption, df in combined.items():
output += df.style.set_table_attributes("style='display:inline'").set_caption(caption)._repr_html_()
output += "\xa0\xa0\xa0"
display(HTML(output))
Usage:
用法:
display_side_by_side([df1, df2, df3], ['caption1', 'caption2', 'caption3'])
Output:
输出:
回答by Private
Here is Jake Vanderplas' solution I came across just the other day:
这是我前几天遇到的 Jake Vanderplas 的解决方案:
import numpy as np
import pandas as pd
class display(object):
"""Display HTML representation of multiple objects"""
template = """<div style="float: left; padding: 10px;">
<p style='font-family:"Courier New", Courier, monospace'>{0}</p>{1}
</div>"""
def __init__(self, *args):
self.args = args
def _repr_html_(self):
return '\n'.join(self.template.format(a, eval(a)._repr_html_())
for a in self.args)
def __repr__(self):
return '\n\n'.join(a + '\n' + repr(eval(a))
for a in self.args)
信用:https: //github.com/jakevdp/PythonDataScienceHandbook/blob/master/notebooks/03.08-Aggregation-and-Grouping.ipynb
回答by Yasin Z?hringer
My solution just builds a table in HTML without any CSS hacks and outputs it:
我的解决方案只是在 HTML 中构建一个表格,没有任何 CSS hacks 并输出它:
import pandas as pd
from IPython.display import display,HTML
def multi_column_df_display(list_dfs, cols=3):
html_table = "<table style='width:100%; border:0px'>{content}</table>"
html_row = "<tr style='border:0px'>{content}</tr>"
html_cell = "<td style='width:{width}%;vertical-align:top;border:0px'>{{content}}</td>"
html_cell = html_cell.format(width=100/cols)
cells = [ html_cell.format(content=df.to_html()) for df in list_dfs ]
cells += (cols - (len(list_dfs)%cols)) * [html_cell.format(content="")] # pad
rows = [ html_row.format(content="".join(cells[i:i+cols])) for i in range(0,len(cells),cols)]
display(HTML(html_table.format(content="".join(rows))))
list_dfs = []
list_dfs.append( pd.DataFrame(2*[{"x":"hello"}]) )
list_dfs.append( pd.DataFrame(2*[{"x":"world"}]) )
multi_column_df_display(2*list_dfs)
回答by Antony Hatchkins
This adds headers to @nts's answer:
这将标题添加到@nts 的答案中:
from IPython.display import display_html
def mydisplay(dfs, names=[]):
html_str = ''
if names:
html_str += ('<tr>' +
''.join(f'<td style="text-align:center">{name}</td>' for name in names) +
'</tr>')
html_str += ('<tr>' +
''.join(f'<td style="vertical-align:top"> {df.to_html(index=False)}</td>'
for df in dfs) +
'</tr>')
html_str = f'<table>{html_str}</table>'
html_str = html_str.replace('table','table style="display:inline"')
display_html(html_str, raw=True)
回答by Dinis Cruz
I ended up using HBOX
我最终使用了 HBOX
import ipywidgets as ipyw
def get_html_table(target_df, title):
df_style = target_df.style.set_table_attributes("style='border:2px solid;font-size:10px;margin:10px'").set_caption(title)
return df_style._repr_html_()
df_2_html_table = get_html_table(df_2, 'Data from Google Sheet')
df_4_html_table = get_html_table(df_4, 'Data from Jira')
ipyw.HBox((ipyw.HTML(df_2_html_table),ipyw.HTML(df_4_html_table)))
回答by stevi
Gibbone's answer worked for me! If you want extra space between the tables go to the code he proposed and add this "\xa0\xa0\xa0"
to the following code line.
吉本的回答对我有用!如果您想要表格之间的额外空间,请转到他建议的代码并将其添加"\xa0\xa0\xa0"
到以下代码行中。
display_html(df1_styler._repr_html_()+"\xa0\xa0\xa0"+df2_styler._repr_html_(), raw=True)
回答by Martino Schr?der
I decided to add some extra functionality to Yasin's elegant answer, where one can choose both the number of cols androws; any extra dfs are then added to the bottom. Additionally one can choose in which order to fill the grid (simply change fill keyword to 'cols' or 'rows' as needed)
我决定为 Yasin 的优雅答案添加一些额外的功能,您可以在其中选择列数和行数;然后将任何额外的 dfs 添加到底部。另外可以选择填充网格的顺序(只需根据需要将填充关键字更改为“cols”或“rows”)
import pandas as pd
from IPython.display import display,HTML
def grid_df_display(list_dfs, rows = 2, cols=3, fill = 'cols'):
html_table = "<table style='width:100%; border:0px'>{content}</table>"
html_row = "<tr style='border:0px'>{content}</tr>"
html_cell = "<td style='width:{width}%;vertical-align:top;border:0px'>{{content}}</td>"
html_cell = html_cell.format(width=100/cols)
cells = [ html_cell.format(content=df.to_html()) for df in list_dfs[:rows*cols] ]
cells += cols * [html_cell.format(content="")] # pad
if fill == 'rows': #fill in rows first (first row: 0,1,2,... col-1)
grid = [ html_row.format(content="".join(cells[i:i+cols])) for i in range(0,rows*cols,cols)]
if fill == 'cols': #fill columns first (first column: 0,1,2,..., rows-1)
grid = [ html_row.format(content="".join(cells[i:rows*cols:rows])) for i in range(0,rows)]
display(HTML(html_table.format(content="".join(grid))))
#add extra dfs to bottom
[display(list_dfs[i]) for i in range(rows*cols,len(list_dfs))]
list_dfs = []
list_dfs.extend((pd.DataFrame(2*[{"x":"hello"}]),
pd.DataFrame(2*[{"x":"world"}]),
pd.DataFrame(2*[{"x":"gdbye"}])))
grid_df_display(3*list_dfs)