Pretty Imprimiendo un marco de datos de pandas

113

¿Cómo puedo imprimir un marco de datos de pandas como una buena tabla basada en texto, como la siguiente?

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

Respuestas:

180

Acabo de encontrar una gran herramienta para esa necesidad, se llama tabular .

Imprime datos tabulares y trabaja con archivos 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:

Para suprimir los índices de fila para todos los tipos de datos, pase showindex="never"o showindex=False.

Romain
fuente
5
Si no tiene acceso a la vanguardia, puede hacerlo tabulate([list(row) for row in df.values], headers=list(df.columns))para deshacerse del índice
Pedro M Duarte
1
No funciona muy bien cuando tiene jerarquías en el índice de fila y en las columnas.
Siddharth
Asegúrese de hacerlo print(tabulate(df, **kwargs))y no simplemente tabulate(df, **kwargs); este último mostrará todas las líneas nuevas \n....
Dror
6
Para suprimir la columna de índice de la izquierda, es posible que desee agregar tambiénshowindex=False
Arthur
17

pandas> = 1.0

Si desea una función incorporada para volcar sus datos en alguna rebaja de github, ahora tiene una. Eche un vistazo 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 |

Así es como se ve en github:

ingrese la descripción de la imagen aquí

Tenga en cuenta que aún necesitará tener el tabulatepaquete instalado.

cs95
fuente
16

Si está en el cuaderno Jupyter, puede ejecutar el siguiente código para mostrar interactivamente el marco de datos en una tabla bien formateada.

Esta respuesta se basa en la respuesta to_html ('temp.html') anterior, pero en lugar de crear un archivo, muestra la tabla bien formateada directamente en el cuaderno:

from IPython.display import display, HTML

display(HTML(df.to_html()))

Crédito para este código debido al ejemplo en: Mostrar DataFrame como tabla en iPython Notebook

Mark Andersen
fuente
15

Puede usar prettytable para representar la tabla como texto. El truco consiste en convertir el data_frame en un archivo csv en la memoria y hacer que Prettytable lo lea. Aquí está el código:

from StringIO import StringIO
import prettytable    

output = StringIO()
data_frame.to_csv(output)
output.seek(0)
pt = prettytable.from_csv(output)
print pt
Ofer
fuente
¿Qué versión de pandas era esta?
WAF
4
AFAIK, prettytablese considera en gran medida abandonware. También es una pena, ya que era un buen paquete. :(
dmn
@dmn para que ya no se mantenga?
muon
prettytableno ha tenido un lanzamiento desde el 6 de abril de 2013. tabulatees su predecesor espiritual y tiene lanzamientos regulares, el más reciente el 24 de enero de 2019.
noddy
7

Usé la respuesta de Ofer por un tiempo y la encontré genial en la mayoría de los casos. Desafortunadamente, debido a inconsistencias entre pandas's to_csv y prettytable 's from_csv, tuve que usar prettytable de una manera diferente.

Un caso de falla es un marco de datos que contiene comas:

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

Prettytable genera un error de forma:

Error: Could not determine delimiter

La siguiente función maneja este caso:

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

Si no le importa el índice, use:

def format_for_print2(df):    
    table = PrettyTable(list(df.columns))
    for row in df.itertuples():
        table.add_row(row[1:])
    return str(table)
ejrb
fuente
Hola, la format_for_print()función no parece estar imprimiendo el índice del Pandas DataFrame. Configuré el índice usando df.index.name = 'index'pero esto no imprime la columna de índice con un nombre.
edesz
2

El seguimiento de la respuesta de la marca, si estas no usando Jupyter por alguna razón, por ejemplo, desea hacer alguna prueba rápida en la consola, se puede utilizar el DataFrame.to_stringmétodo, que trabaja a partir de - al menos - pandas 0.12 (2014) en adelante .

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
fuente
0

Quizás estés buscando algo como esto:

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)
Salida:
+ ------- + ---- + ----- +
| a | b | c |
+ ------- + ---- + ----- +
| 1 | 2 | 3 |
| 11111 | 22 | 333 |
+ ------- + ---- + ----- +
Pafkone
fuente
-5

Quería una impresión en papel de un marco de datos, pero también quería agregar algunos resultados y comentarios en la misma página. He trabajado en lo anterior y no pude obtener lo que quería. Terminé usando declaraciones file.write (df1.to_csv ()) y file.write (",,, blah ,,,,,, bla") para obtener mis extras en la página. Cuando abrí el archivo csv, fue directamente a una hoja de cálculo que imprimió todo en el formato y ritmo correctos.

Jon
fuente