Jolie impression d'un dataframe pandas

114

Comment puis-je imprimer un dataframe pandas comme un joli tableau textuel, comme suit?

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

Réponses:

181

Je viens de trouver un excellent outil pour ce besoin, il s'appelle tabulate .

Il imprime des données tabulaires et fonctionne avec 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        |
+----+-----------+-------------+

Remarque:

Pour supprimer les index de ligne pour tous les types de données, transmettez showindex="never"ou showindex=False.

Romain
la source
5
Si vous n'avez pas accès à la pointe de la technologie, vous pouvez faire tabulate([list(row) for row in df.values], headers=list(df.columns))pour vous débarrasser de l'index
Pedro M Duarte
1
Ne fonctionne pas très bien lorsque vous avez des hiérarchies dans l'index de ligne et les colonnes.
Siddharth
Assurez-vous de le faire print(tabulate(df, **kwargs))et pas simplement tabulate(df, **kwargs); ce dernier affichera toutes les nouvelles lignes \n....
Dror
6
Pour supprimer la colonne d'index de gauche, vous pouvez également ajoutershowindex=False
Arthur
19

pandas> = 1.0

Si vous voulez une fonction intégrée pour vider vos données dans un markdown github, vous en avez maintenant un. Jetez un œil à 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 |

Voici à quoi cela ressemble sur github:

entrez la description de l'image ici

Notez que vous devrez toujours tabulateinstaller le package.

cs95
la source
16

Si vous êtes dans le bloc-notes Jupyter, vous pouvez exécuter le code suivant pour afficher de manière interactive le dataframe dans un tableau bien formaté.

Cette réponse s'appuie sur la réponse to_html ('temp.html') ci-dessus, mais au lieu de créer un fichier, la table bien formatée s'affiche directement dans le bloc-notes:

from IPython.display import display, HTML

display(HTML(df.to_html()))

Crédit pour ce code en raison de l'exemple sur: Afficher DataFrame en tant que table dans iPython Notebook

Mark Andersen
la source
15

Vous pouvez utiliser prettytable pour rendre le tableau sous forme de texte. L'astuce consiste à convertir le data_frame en fichier csv en mémoire et à le faire lire par prettytable. Voici le code:

from StringIO import StringIO
import prettytable    

output = StringIO()
data_frame.to_csv(output)
output.seek(0)
pt = prettytable.from_csv(output)
print pt
Ofer
la source
De quelle version de pandas s'agissait-il?
WAF
4
AFAIK, prettytableest largement considéré comme abandonware. Dommage aussi, car c'était un joli paquet. :(
dmn
@dmn donc il n'est plus maintenu?
muon
prettytablen'a pas eu de sortie depuis le 6 avril 2013. tabulateest son prédécesseur spirituel et a des versions régulières, la plus récente étant le 24 janvier 2019.
noddy
7

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

Un cas d'échec est un dataframe contenant des virgules:

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

Prettytable lève une erreur du formulaire:

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'index, utilisez:

def format_for_print2(df):    
    table = PrettyTable(list(df.columns))
    for row in df.itertuples():
        table.add_row(row[1:])
    return str(table)
ejrb
la source
Salut, la format_for_print()fonction ne semble pas imprimer l'index du Pandas DataFrame. J'ai défini l'index en utilisant df.index.name = 'index'mais cela n'imprime pas la colonne d'index avec un nom.
edesz
2

Suite à la réponse de Mark, si vous n'utilisez pas Jupyter pour une raison quelconque, par exemple si vous voulez faire des tests rapides sur la console, vous pouvez utiliser la DataFrame.to_stringméthode, qui fonctionne à partir - au moins - de 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
sigint
la source
0

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)
Production:
+ ------- + ---- + ----- +
| a | b | c |
+ ------- + ---- + ----- +
| 1 | 2 | 3 |
| 11111 | 22 | 333 |
+ ------- + ---- + ----- +
Pafkone
la source
-6

Je voulais une impression papier d'un dataframe mais je voulais aussi ajouter quelques résultats et commentaires sur la même page. J'ai travaillé sur ce qui précède et je n'ai pas pu obtenir ce que je voulais. J'ai fini par utiliser les instructions file.write (df1.to_csv ()) et file.write (",,, blah ,,,,,, blah") pour obtenir mes extras sur la page. Lorsque j'ai ouvert le fichier csv, il est allé directement à une feuille de calcul qui a tout imprimé dans le bon rythme et le bon format.

Jon
la source