Saya memiliki dua kerangka data panda dan saya ingin menampilkannya di notebook Jupyter.
Melakukan sesuatu seperti:
display(df1)
display(df2)
Tunjukkan satu sama lain di bawah ini:
Saya ingin memiliki kerangka data kedua di sebelah kanan yang pertama. Ada pertanyaan serupa , tetapi sepertinya ada orang yang puas dengan menggabungkan mereka dalam satu kerangka data untuk menunjukkan perbedaan di antara mereka.
Ini tidak akan berhasil untuk saya. Dalam kasus saya, kerangka data dapat mewakili sama sekali berbeda (elemen yang tidak dapat dibandingkan) dan ukurannya bisa berbeda. Jadi tujuan utama saya adalah menghemat ruang.
pandas
ipython-notebook
jupyter-notebook
Salvador Dali
sumber
sumber
Jawaban:
Anda dapat mengganti CSS dari kode keluaran. Ini digunakan
flex-direction: column
secara default. Coba ubah menjadirow
sebagai gantinya. Berikut contohnya:import pandas as pd import numpy as np from IPython.display import display, HTML CSS = """ .output { flex-direction: row; } """ HTML('<style>{}</style>'.format(CSS))
Anda dapat, tentu saja, menyesuaikan CSS sesuai keinginan Anda.
Jika Anda ingin menargetkan hanya satu keluaran sel, coba gunakan
:nth-child()
selektor. Misalnya, kode ini akan mengubah CSS dari output hanya sel ke-5 di notebook:CSS = """ div.cell:nth-child(5) .output { flex-direction: row; } """
sumber
HTML('<style>{}</style>'.format(CSS))
adalah baris terakhir dalam sel (dan jangan lupa untuk menggunakan pemilih anak ke-n). Namun, ini dapat menyebabkan masalah dengan pemformatan, jadi solusi Anda lebih baik. (+1)HTML('<style>.output {flex-direction: row;}</style>')
demi kesederhanaanSaya akhirnya menulis fungsi yang dapat melakukan ini:
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)
Contoh penggunaan:
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)
sumber
*args
alih-alih hanyadf
? Apakah karena Anda dapat memiliki banyak masukan*args
? 2) Bagian mana dari fungsi Anda yang membuat df ke-2 dan selanjutnya ditambahkan ke kanan yang pertama, bukan di bawahnya? Apakah itu'table style="display:inline"'
bagiannya? Terima kasih lagiStyler
s, bukanDataFrame
s. Dalam hal ini, menggunakanhtml_str+=df.render()
bukanhtml_str+=df.to_html()
.Mulai dari
pandas 0.17.1
visualisasi DataFrames bisa langsung dimodifikasi dengan metode pandas stylingUntuk menampilkan dua DataFrames secara berdampingan, Anda harus menggunakan
set_table_attributes
argumen"style='display:inline'"
seperti yang disarankan dalam jawaban ntg . Ini akan mengembalikan duaStyler
objek. Untuk menampilkan dataframe selaras, cukup kirimkan representasi HTML mereka yang digabungkan melaluidisplay_html
metode dari IPython.Dengan metode ini juga lebih mudah untuk menambahkan opsi styling lainnya. Berikut cara menambahkan keterangan, seperti yang diminta di sini :
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('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)
sumber
Menggabungkan pendekatan gibbone (untuk mengatur gaya dan teks) dan stevi (menambahkan spasi) Saya membuat versi fungsi saya, yang mengeluarkan pandas dataframes sebagai tabel berdampingan:
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))
Pemakaian:
display_side_by_side([df1, df2, df3], ['caption1', 'caption2', 'caption3'])
Keluaran:
sumber
Inilah solusi Jake Vanderplas yang saya temui beberapa hari yang lalu:
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)
Kredit: https://github.com/jakevdp/PythonDataScienceHandbook/blob/master/notebooks/03.08-Aggregation-and-Grouping.ipynb
sumber
Solusi saya hanya membuat tabel dalam HTML tanpa peretasan CSS dan mengeluarkannya:
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)
sumber
Ini menambahkan header ke jawaban @ 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)
sumber
mydisplay((df1,df2))
hanya memberi,df.to_html(index=False) df.to_html(index=False)
bukan konten dataframe. Juga, ada tanda '}' ekstra di f'string '.Saya akhirnya menggunakan 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)))
sumber
Jawaban Gibbone berhasil untuk saya! Jika Anda ingin spasi ekstra di antara tabel, buka kode yang dia usulkan dan tambahkan ini
"\xa0\xa0\xa0"
ke baris kode berikut.display_html(df1_styler._repr_html_()+"\xa0\xa0\xa0"+df2_styler._repr_html_(), raw=True)
sumber
Saya memutuskan untuk menambahkan beberapa fungsionalitas ekstra pada jawaban Yasin yang elegan, di mana seseorang dapat memilih jumlah kolom dan baris; setiap df tambahan kemudian ditambahkan ke bawah. Selain itu, seseorang dapat memilih di mana urutan untuk mengisi kisi (cukup ubah kata kunci isian menjadi 'kolom' atau 'baris' sesuai kebutuhan)
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)
hasil tes
sumber
Kode @zarak cukup kecil tetapi memengaruhi tata letak seluruh buku catatan. Pilihan lain agak berantakan bagi saya.
Saya telah menambahkan beberapa CSS yang jelas ke jawaban ini yang hanya mempengaruhi keluaran sel saat ini. Anda juga dapat menambahkan apa pun di bawah atau di atas kerangka data.
from ipywidgets import widgets, Layout from IPython import display import pandas as pd import numpy as np # sample data df1 = pd.DataFrame(np.random.randn(8, 3)) df2 = pd.DataFrame(np.random.randn(8, 3)) # create output widgets widget1 = widgets.Output() widget2 = widgets.Output() # render in output widgets with widget1: display.display(df1.style.set_caption('First dataframe')) df1.info() with widget2: display.display(df2.style.set_caption('Second dataframe')) df1.info() # add some CSS styles to distribute free space box_layout = Layout(display='flex', flex_flow='row', justify_content='space-around', width='auto' ) # create Horisontal Box container hbox = widgets.HBox([widget1, widget2], layout=box_layout) # render hbox hbox
sumber
Perpanjangan jawaban antony Jika Anda ingin membatasi de visualisasi tabel menjadi beberapa angka blok demi baris, gunakan variabel maxTables.
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)
sumber