Jupyter notebook display two pandas tables side by side

后端 未结 12 1902
迷失自我
迷失自我 2020-12-04 04:56

I have two pandas dataframes and I would like to display them in Jupyter notebook.

Doing something like:

display(df1)
display(df2)

相关标签:
12条回答
  • 2020-12-04 05:50

    Starting from pandas 0.17.1 the visualization of DataFrames can be directly modified with pandas styling methods

    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.

    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)
    

    0 讨论(0)
  • 2020-12-04 05:53

    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.

    display_html(df1_styler._repr_html_()+"\xa0\xa0\xa0"+df2_styler._repr_html_(), raw=True)
    
    0 讨论(0)
  • 2020-12-04 05:55

    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:

    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.

    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:

    CSS = """
    div.cell:nth-child(5) .output {
        flex-direction: row;
    }
    """
    
    0 讨论(0)
  • 2020-12-04 05:58

    My solution just builds a table in HTML without any CSS hacks and outputs it:

    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

    0 讨论(0)
  • 2020-12-04 05:58

    This adds headers to @nts's answer:

    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)
    

    0 讨论(0)
  • 2020-12-04 05:58

    @zarak code is pretty small but affects the layout of the whole notebook. Other options are a bit messy for me.

    I've added some clear CSS to this answer affecting only current cell output. Also you are able to add anything below or above dataframes.

    from ipywidgets import widgets, Layout
    from IPython import display
    import pandas as pd
    import numpy as np
    
    # sample data
    df1 = pd.DataFrame(np.random.randn(8, 3))
    df2 = pd.DataFrame(np.random.randn(8, 3))
    
    # create output widgets
    widget1 = widgets.Output()
    widget2 = widgets.Output()
    
    # render in output widgets
    with widget1:
        display.display(df1.style.set_caption('First dataframe'))
        df1.info()
    with widget2:
        display.display(df2.style.set_caption('Second dataframe'))
        df1.info()
    
    
    # add some CSS styles to distribute free space
    box_layout = Layout(display='flex',
                        flex_flow='row',
                        justify_content='space-around',
                        width='auto'
                       )
        
    # create Horisontal Box container
    hbox = widgets.HBox([widget1, widget2], layout=box_layout)
    
    # render hbox
    hbox
    

    0 讨论(0)
提交回复
热议问题