web-dev-qa-db-ja.com

Jupyterノートブックには2つのpandasテーブルが並んで表示されます

2つのpandasデータフレームがあり、それらをJupyterノートブックに表示したいと思います。

次のようなことをする:

display(df1)
display(df2)

それらを次の下に表示します。

enter image description here

最初のデータフレームの右側に2番目のデータフレームが必要です。 同様の質問 がありますが、人はそれらの違いを示す1つのデータフレームにそれらをマージすることに満足しているようです。

これは私にはうまくいきません。私の場合、データフレームは完全に異なる(比較できない要素)を表すことができ、それらのサイズは異なる場合があります。したがって、私の主な目標はスペースを節約することです。

59
Salvador Dali

出力コードの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))

Jupyter image

もちろん、必要に応じてCSSをさらにカスタマイズできます。

1つのセルの出力のみをターゲットにしたい場合は、:nth-child()セレクターを使用してみてください。たとえば、次のコードは、ノートブックの5番目のセルのみの出力のCSSを変更します。

CSS = """
div.cell:nth-child(5) .output {
    flex-direction: row;
}
"""
56
zarak

私はこれを行うことができる関数を書くことになりました:

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)

enter image description here

74
ntg

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)

aligned dataframes pandas styler

この方法を使用すると、他のスタイルオプションを簡単に追加できます。要求に応じてキャプションを追加する方法は次のとおりです 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)

aligned dataframes pandas styler with caption

15
gibbone

先日出会った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

9
Private

私のソリューションは、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)

Output

8

これにより、@ 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)

enter image description here

7

私は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)))
1
Dinis Cruz

ギブボーンの答えは私のために働いた!テーブル間に余分なスペースが必要な場合は、彼が提案したコードに移動し、この"\xa0\xa0\xa0"を次のコード行に追加します。

display_html(df1_styler._repr_html_()+"\xa0\xa0\xa0"+df2_styler._repr_html_(), raw=True)
1
stevi