Jupyter notebook display two pandas tables side by side

后端 未结 12 1901
迷失自我
迷失自我 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:31

    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:

    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:

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

    I ended up using 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)))
    
    0 讨论(0)
  • 2020-12-04 05:33

    I decided to add some extra functionality to Yasin's elegant answer, where one can choose both the number of cols and rows; 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)

    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)
    

    test output

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

    Here is Jake Vanderplas' solution I came across just the other day:

    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)
    

    Credit: https://github.com/jakevdp/PythonDataScienceHandbook/blob/master/notebooks/03.08-Aggregation-and-Grouping.ipynb

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

    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)
    

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

    Extension of antony's answer If you want to limit de visualization of tables to some numer of blocks by row, use the maxTables variable.

    def mydisplay(dfs, names=[]):
    
        count = 0
        maxTables = 6
    
        if not names:
            names = [x for x in range(len(dfs))]
    
        html_str = ''
        html_th = ''
        html_td = ''
    
        for df, name in zip(dfs, names):
            if count <= (maxTables):
                html_th += (''.join(f'<th style="text-align:center">{name}</th>'))
                html_td += (''.join(f'<td style="vertical-align:top"> {df.to_html(index=False)}</td>'))
                count += 1
            else:
                html_str += f'<tr>{html_th}</tr><tr>{html_td}</tr>'
                html_th = f'<th style="text-align:center">{name}</th>'
                html_td = f'<td style="vertical-align:top"> {df.to_html(index=False)}</td>'
                count = 0
    
    
        if count != 0:
            html_str += f'<tr>{html_th}</tr><tr>{html_td}</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)
提交回复
热议问题