2つのpandasデータフレームがあり、それらをJupyterノートブックに表示したいと思います。
次のようなことをする:
display(df1)
display(df2)
それらを次の下に表示します。
最初のデータフレームの右側に2番目のデータフレームが必要です。 同様の質問 がありますが、人はそれらの違いを示す1つのデータフレームにそれらをマージすることに満足しているようです。
これは私にはうまくいきません。私の場合、データフレームは完全に異なる(比較できない要素)を表すことができ、それらのサイズは異なる場合があります。したがって、私の主な目標はスペースを節約することです。
出力コードの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))
もちろん、必要に応じてCSSをさらにカスタマイズできます。
1つのセルの出力のみをターゲットにしたい場合は、:nth-child()
セレクターを使用してみてください。たとえば、次のコードは、ノートブックの5番目のセルのみの出力のCSSを変更します。
CSS = """
div.cell:nth-child(5) .output {
flex-direction: row;
}
"""
私はこれを行うことができる関数を書くことになりました:
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)
使用例:
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)
pandas 0.17.1
から開始して、DataFrameの視覚化は pandasスタイリングメソッド で直接変更できます。
2つのDataFrameを並べて表示するには、 ntg answer で提案されているように、set_table_attributes
を引数"style='display:inline'"
とともに使用する必要があります。これにより、2つのStyler
オブジェクトが返され、位置合わせされたデータフレームがIPythonのdisplay_html
メソッドを介して結合されたHTML表現を渡すだけで表示されます。
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('Table 1')
df2_styler = df2.style.set_table_attributes("style='display:inline'").set_caption('Table 2')
display_html(df1_styler._repr_html_()+df2_styler._repr_html_(), raw=True)
この方法を使用すると、他のスタイルオプションを簡単に追加できます。要求に応じてキャプションを追加する方法は次のとおりです here :
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)
先日出会った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)
私のソリューションは、CSSハッキングなしでHTMLでテーブルを作成し、出力するだけです。
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)
これにより、@ 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)
私は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)))
ギブボーンの答えは私のために働いた!テーブル間に余分なスペースが必要な場合は、彼が提案したコードに移動し、この"\xa0\xa0\xa0"
を次のコード行に追加します。
display_html(df1_styler._repr_html_()+"\xa0\xa0\xa0"+df2_styler._repr_html_(), raw=True)