Pretty Printing a pandas dataframe


114

Come posso stampare un dataframe panda come una bella tabella di testo, come la seguente?

+------------+---------+-------------+
| column_one | col_two |   column_3  |
+------------+---------+-------------+
|          0 |  0.0001 | ABCD        |
|          1 |  1e-005 | ABCD        |
|          2 |  1e-006 | long string |
|          3 |  1e-007 | ABCD        |
+------------+---------+-------------+

Risposte:


181

Ho appena trovato un ottimo strumento per questa esigenza, si chiama tabulate .

Stampa dati tabulari e lavora con DataFrame.

from tabulate import tabulate
import pandas as pd

df = pd.DataFrame({'col_two' : [0.0001, 1e-005 , 1e-006, 1e-007],
                   'column_3' : ['ABCD', 'ABCD', 'long string', 'ABCD']})
print(tabulate(df, headers='keys', tablefmt='psql'))

+----+-----------+-------------+
|    |   col_two | column_3    |
|----+-----------+-------------|
|  0 |    0.0001 | ABCD        |
|  1 |    1e-05  | ABCD        |
|  2 |    1e-06  | long string |
|  3 |    1e-07  | ABCD        |
+----+-----------+-------------+

Nota:

Per sopprimere gli indici di riga per tutti i tipi di dati, passare showindex="never"o showindex=False.


5
Se non hai accesso al bleeding edge, puoi fare tabulate([list(row) for row in df.values], headers=list(df.columns))per sbarazzarti dell'indice
Pedro M Duarte

1
Non funziona molto bene quando sono presenti gerarchie nell'indice di riga e nelle colonne.
Siddharth,

Assicurati di farlo print(tabulate(df, **kwargs))e non semplicemente tabulate(df, **kwargs); quest'ultimo mostrerà tutte le nuove linee \n....
Dror

6
Per sopprimere la colonna dell'indice di sinistra si potrebbe voler aggiungere ancheshowindex=False
Arthur


18

panda> = 1.0

Se vuoi una funzione incorporata per scaricare i tuoi dati in qualche markdown di GitHub, ora ne hai uno. Dai uno sguardo a to_markdown:

df = pd.DataFrame({"A": [1, 2, 3], "B": [1, 2, 3]}, index=['a', 'a', 'b'])  
print(df.to_markdown()) 

|    |   A |   B |
|:---|----:|----:|
| a  |   1 |   1 |
| a  |   2 |   2 |
| b  |   3 |   3 |

Ecco come appare su GitHub:

inserisci qui la descrizione dell'immagine

Nota che dovrai comunque avere il tabulatepacchetto installato.


16

Se sei in Jupyter notebook, puoi eseguire il codice seguente per visualizzare in modo interattivo il dataframe in una tabella ben formattata.

Questa risposta si basa sulla risposta to_html ('temp.html') sopra, ma invece di creare un file visualizza la tabella ben formattata direttamente nel taccuino:

from IPython.display import display, HTML

display(HTML(df.to_html()))

Credito per questo codice dovuto all'esempio in: Mostra DataFrame come tabella in iPython Notebook


15

Puoi usare prettytable per rendere la tabella come testo. Il trucco è convertire il data_frame in un file csv in memoria e farlo leggere in modo carino. Ecco il codice:

from StringIO import StringIO
import prettytable    

output = StringIO()
data_frame.to_csv(output)
output.seek(0)
pt = prettytable.from_csv(output)
print pt

Quale versione di panda era questa?
WAF

4
AFAIK, prettytableè in gran parte considerato abbandonato. Peccato anche perché era un bel pacchetto. :(
dmn

@dmn quindi non è più mantenuto?
muone

prettytablenon ha avuto un rilascio dal 6 aprile 2013. tabulateè il suo predecessore spirituale e ha versioni regolari, la più recente è stata il 24 gennaio 2019.
noddy

7

Ho usato la risposta di Ofer per un po 'e l'ho trovata fantastica nella maggior parte dei casi. Sfortunatamente, a causa delle incongruenze tra to_csv di pandas e from_csv di prettytable, ho dovuto usare prettytable in un modo diverso.

Un caso di errore è un dataframe contenente virgole:

pd.DataFrame({'A': [1, 2], 'B': ['a,', 'b']})

Prettytable solleva un errore del modulo:

Error: Could not determine delimiter

La seguente funzione gestisce questo caso:

def format_for_print(df):    
    table = PrettyTable([''] + list(df.columns))
    for row in df.itertuples():
        table.add_row(row)
    return str(table)

Se non ti interessa l'indice, usa:

def format_for_print2(df):    
    table = PrettyTable(list(df.columns))
    for row in df.itertuples():
        table.add_row(row[1:])
    return str(table)

Salve, la format_for_print()funzione non sembra stampare l'indice del Pandas DataFrame. Ho impostato l'indice usando df.index.name = 'index'ma questo non stampa la colonna dell'indice con un nome.
edesz

2

Facendo seguito alla risposta di Marco, se stai non usando Jupyter per qualche motivo, ad esempio, si vuole fare qualche test rapido sulla console, è possibile utilizzare il DataFrame.to_stringmetodo, che funziona da - almeno - Pandas 0,12 (2014) in poi .

import pandas as pd

matrix = [(1, 23, 45), (789, 1, 23), (45, 678, 90)]
df = pd.DataFrame(matrix, columns=list('abc'))
print(df.to_string())

#  outputs:
#       a    b   c
#  0    1   23  45
#  1  789    1  23
#  2   45  678  90

0

Forse stai cercando qualcosa del genere:

def tableize(df):
    if not isinstance(df, pd.DataFrame):
        return
    df_columns = df.columns.tolist() 
    max_len_in_lst = lambda lst: len(sorted(lst, reverse=True, key=len)[0])
    align_center = lambda st, sz: "{0}{1}{0}".format(" "*(1+(sz-len(st))//2), st)[:sz] if len(st) < sz else st
    align_right = lambda st, sz: "{0}{1} ".format(" "*(sz-len(st)-1), st) if len(st) < sz else st
    max_col_len = max_len_in_lst(df_columns)
    max_val_len_for_col = dict([(col, max_len_in_lst(df.iloc[:,idx].astype('str'))) for idx, col in enumerate(df_columns)])
    col_sizes = dict([(col, 2 + max(max_val_len_for_col.get(col, 0), max_col_len)) for col in df_columns])
    build_hline = lambda row: '+'.join(['-' * col_sizes[col] for col in row]).join(['+', '+'])
    build_data = lambda row, align: "|".join([align(str(val), col_sizes[df_columns[idx]]) for idx, val in enumerate(row)]).join(['|', '|'])
    hline = build_hline(df_columns)
    out = [hline, build_data(df_columns, align_center), hline]
    for _, row in df.iterrows():
        out.append(build_data(row.tolist(), align_right))
    out.append(hline)
    return "\n".join(out)


df = pd.DataFrame([[1, 2, 3], [11111, 22, 333]], columns=['a', 'b', 'c'])
print tableize(df)
Produzione:
+ ------- + ---- + ----- +
| a | b | c |
+ ------- + ---- + ----- +
| 1 | 2 | 3 |
| 11111 | 22 | 333 |
+ ------- + ---- + ----- +

-6

Volevo una stampa cartacea di un dataframe ma volevo aggiungere anche alcuni risultati e commenti sulla stessa pagina. Ho lavorato su quanto sopra e non sono riuscito a ottenere ciò che volevo. Ho finito per utilizzare le istruzioni file.write (df1.to_csv ()) e file.write (",,, blah ,,,,,, blah") per ottenere i miei extra sulla pagina. Quando ho aperto il file csv è andato direttamente a un foglio di calcolo che ha stampato tutto con il ritmo e il formato giusti.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.