2016-08-05 32 views
26

Mam dwie ramki danych pandy i chciałbym je wyświetlić w notesie Jupyter.Notebook Jupyter wyświetla dwa stoły pandy obok siebie

Uprawiając odczuwalna:

display(df1) 
display(df2) 

pokazuje je jeden poniżej drugiego:

enter image description here

chciałbym mieć drugi dataframe na prawo od pierwszego. Jest a similar question, ale wygląda na to, że dana osoba jest zadowolona z połączenia ich w jedną ramkę danych, pokazującą różnicę między nimi.

To nie będzie działać dla mnie. W moim przypadku ramki danych mogą reprezentować zupełnie inne (nieporównywalne elementy), a ich rozmiar może być inny. Dlatego moim głównym celem jest oszczędzanie przestrzeni.

+0

Zamieściłem Jake Vanderplas' rozwiązanie . Ładny, czysty kod. – Private

Odpowiedz

28

Można przesłonić kod CSS kodu wyjściowego. Domyślnie używa flex-direction: column. Spróbuj zmienić go na row. Oto przykład:

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

Możesz, oczywiście, dalej, jak chcesz dostosować CSS.

Jeśli chcesz kierować tylko na wyjście jednej komórki, spróbuj użyć selektora :nth-child(). Na przykład, kod ten będzie modyfikować CSS wyjścia zaledwie 5. komórki w notesie:

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

Co, jeśli chcę nadać im osobny tytuł? Próbowałem to zrobić, nie byłem w stanie tego zrobić. –

+2

To rozwiązanie wpływa na wszystkie komórki. Jak mogę to zrobić tylko dla jednej komórki? – jrovegno

+0

@NeerajKomuravalli Najlepiej byłoby zapytać o to jako nowe pytanie. Nie jestem pewien łatwego sposobu zrobienia tego z mojej głowy. – zarak

6

Moje rozwiązanie właśnie buduje tabelę w HTML bez żadnych hacków CSS i wyjść to:

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

I skończyło się pisząc funkcję, która może to zrobić:

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) 

Przykład użycia:

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

To jest naprawdę świetne, dzięki. Jak łatwo lub w inny sposób byłoby dodać nazwę ramki danych nad każdym wyjściem, jak myślisz? –

+1

Pojawią się dwa problemy: 1. znajomość nazw ramek danych jest poza zakresem imho https://stackoverflow.com/questions/2749796/how-to-get-the-original-nazwa_zmiennej-zmiennej- przekazywana do funkcji, ale może wykonywać https://stackoverflow.com/questions/218616/getting-method-parameter-names-in-python lub przekazywać je jako parametry) 2. Potrzebowałbyś dodatkowego html i jego otwartego zakończył/do ciebie co zrobić ... tutaj jest podstawowy przykład tego, jak ta część mogła wyglądać: https://i.stack.imgur.com/mIVsD.png – ntg

6

Oto Jake Vanderplas' rozwiązanie natknąłem się tylko na drugi dzień:

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) 

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