Jupyter ordinateur portable afficher deux tables de pandas côte à côte

j'ai deux bases de données pandas et je voudrais les afficher dans le carnet Jupyter.

de Faire quelque chose comme:

display(df1)
display(df2)

les Montre l'un au-dessous de l'autre:

enter image description here

j'aimerais avoir une deuxième base de données à droite de la première. Il ya une question similaire , mais il semble qu'Il ya une personne est satisfait soit de les fusionner dans une base de données de montrer la différence entre eux.

ça ne marchera pas pour moi. Dans mon cas, les dataframes peuvent représenter des éléments complètement différents (non comparables) et leur taille peut être différente. Ainsi mon but principal est de sauver de l'espace.

33
demandé sur Community 2016-08-05 09:58:08

6 réponses

vous pouvez outrepasser le CSS du code de sortie. Il utilise flex-direction: column par défaut. Essayez de le changer en row à la place. Voici un exemple:

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

vous pouvez, bien sûr, personnaliser le CSS plus loin que vous le souhaitez.

si vous souhaitez cibler seulement la sortie d'une cellule, essayez d'utiliser le sélecteur :nth-child() . Par exemple, ce code modifiera le CSS de la sortie de seulement la 5ème cellule dans le bloc-notes:

CSS = """
div.cell:nth-child(5) .output {
    flex-direction: row;
}
"""
40
répondu zarak 2017-01-28 13:39:39

j'ai fini par écrire une fonction qui peut faire ceci:

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)

exemple d'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)

enter image description here

43
répondu ntg 2017-07-05 10:42:16

à partir de pandas 0.17.1 la visualisation des images de données peut être directement modifiée avec pandas méthodes de style

pour afficher deux images de données côte à côte, vous devez utiliser set_table_attributes avec l'argument "style='display:inline'" comme suggéré dans ntg answer . Ceci retournera deux objets Styler , pour afficher les images alignées il suffit de passer leur représentation HTML jointe par la méthode display_html de IPython:

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

Avec cette méthode est également plus facile d'ajouter d'autres options de style. Voici comment ajouter une légende, comme demandé ici :

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

8
répondu gibbone 2018-06-17 18:13:59

ma solution ne fait que construire une table en HTML sans aucun Hack CSS et la sort:

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

7
répondu Yasin Zähringer 2017-03-17 21:27:10

Voici la solution de Jake Vanderplas je suis tombé sur juste l'autre jour:

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)

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

7
répondu Private 2017-09-21 13:37:34

cela ajoute des en-têtes à la réponse de @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

3
répondu Antony Hatchkins 2018-06-18 17:46:04