205 votes

Impression jolie d'un dataframe pandas

Comment puis-je imprimer un dataframe pandas sous la forme d'un joli tableau textuel, comme le suivant ?

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

11voto

sigint Points 938

Pour faire suite à la réponse de Mark, si vous êtes no Si vous utilisez Jupyter pour une raison ou une autre, par exemple si vous souhaitez effectuer des tests rapides sur la console, vous pouvez utiliser l'outil de gestion de l'environnement Jupyter. DataFrame.to_string qui fonctionne au moins depuis Pandas 0.12 (2014).

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

8voto

ejrb Points 328

J'ai utilisé la réponse d'Ofer pendant un certain temps et je l'ai trouvée excellente dans la plupart des cas. Malheureusement, en raison d'incohérences entre to_csv de pandas y jolie table de from_csv, j'ai dû utiliser prettytable d'une manière différente.

Un cas d'échec est un cadre de données contenant des virgules :

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

Prettytable soulève une erreur de la forme :

Error: Could not determine delimiter

La fonction suivante gère ce cas :

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

Si vous ne vous souciez pas de l'indice, utilisez :

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

5voto

Pafkone Points 31

Peut-être que vous cherchez quelque chose comme ça :

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)

Output:
+-------+----+-----+
|    a  |  b |   c |
+-------+----+-----+
|     1 |  2 |   3 |
| 11111 | 22 | 333 |
+-------+----+-----+

1voto

Mise à jour : Une solution encore meilleure est de simplement mettre le nom de la variable du dataframe sur la dernière ligne de la cellule. L'impression se fera automatiquement dans un joli format.

import pandas as pd
import numpy as np

df = pd.DataFrame({'Data1': np.linspace(0,10,11), 'Data2': np.linspace(10,0,11)})
df

0voto

Spartan Points 140

J'utilise le riche pour cela, il a des tableaux plus jolis que ceux basés sur des tableaux. .to_markdown( ).

import pandas as pd
from rich.console import Console
from rich.table import Table
df = pd.DataFrame({'col_two' : [0.0001, 1e-005 , 1e-006, 1e-007],
                   'column_3' : ['ABCD', 'ABCD', 'long string', 'ABCD']})
console = Console()
table = Table('Title')
table.add_row(df.to_string(float_format=lambda _: '{:.4f}'.format(_)))
console.print(table)

Ça vous donne cette table :

enter image description here

Consultez la documentation pour plus d'options de personnalisation :

https://rich.readthedocs.io/en/stable/tables.html

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X