2016-08-05 46 views
26

Ich habe zwei Pandas Datenrahmen und möchte sie in Jupyter Notebook anzeigen.Jupyter Notebook-Display zwei Pandaboards nebeneinander

tut so etwas wie:

display(df1) 
display(df2) 

sie Shows untereinander:

enter image description here

Ich mag würde einen zweiten Datenrahmen auf dem rechten Seite des ersten haben. Es gibt a similar question, aber es sieht so aus, als ob eine Person entweder damit zufrieden ist, sie in einem Datenrahmen zu vereinen, um den Unterschied zwischen ihnen zu zeigen.

Dies wird nicht für mich arbeiten. In meinem Fall können Datenrahmen völlig verschiedene (nicht vergleichbare Elemente) darstellen und ihre Größe kann unterschiedlich sein. Mein Hauptziel ist also, Platz zu sparen.

+0

Ich stellte Jake Vanderplas' Lösung . Netter, sauberer Code. – Private

Antwort

28

Sie könnten das CSS des Ausgabecodes überschreiben. Es verwendet flex-direction: column standardmäßig. Versuchen Sie stattdessen, es in row zu ändern. Hier ein Beispiel:

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

Sie könnten natürlich anpassen, um die CSS weiter, wie Sie möchten.

Wenn Sie nur den Ausgang einer Zelle ansprechen möchten, versuchen Sie es mit dem Selektor :nth-child(). Zum Beispiel wird dieser Code der CSS der Ausgabe von nur die 5. Zelle im Notebook ändern:

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

Was, wenn ich beiden einen separaten Titel geben möchte? Versucht, es zu tun, konnte es nicht tun –

+2

Diese Lösung betrifft alle Zellen, Wie kann ich dies nur für eine Zelle tun? – jrovegno

+0

@NeerajKomuravalli Es wäre wahrscheinlich das Beste, dies als eine neue Frage zu stellen. Ich bin mir nicht sicher, ob ich das leicht von oben machen könnte. – zarak

6

Meine Lösung nur eine Tabelle in HTML erstellt ohne CSS-Hacks und gibt es:

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

25

ich habe eine Funktion Schreiben endete, können dies tun:

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) 

Beispiel Nutzung:

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

+0

Das ist wirklich großartig, danke. Wie leicht oder anders würde es sein, den Namen des Datenrahmens über jeden Ausgang zu setzen, findest du? –

+1

Es gäbe zwei Probleme: 1. die Namen der Datenframes zu kennen ist außerhalb des Geltungsbereichs imho https://stackoverflow.com/questions/2749796/how-to-get-the-original-variable-name-of-variable- passed-to-a-function, kann aber https://stackoverflow.com/questions/218616/getting-method-parameter-names-in-python tun oder sie als params übergeben. 2. Du brauchst extra html und es ist offen beendet/bis zu dir was zu tun ist ... hier ist ein grundlegendes Beispiel wie dieses Teil aussehen könnte: https://i.stack.imgur.com/mIVsD.png – ntg

6

Hier ist Jake Vanderplas' I-Lösung über nur den anderen Tag kam:

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