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:
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.
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))
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;
}
"""
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)
à 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)
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)
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)
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)
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)