Sé que he visto algún ejemplo en alguna parte antes, pero por mi vida no puedo encontrarlo cuando busco en Google.
Tengo algunas filas de datos:
data = [[1,2,3],
[4,5,6],
[7,8,9],
]
Y quiero generar estos datos en una tabla, por ejemplo
+---+---+---+
| 1 | 2 | 3 |
+---+---+---+
| 4 | 5 | 6 |
+---+---+---+
| 7 | 8 | 9 |
+---+---+---+
Obviamente, podría usar una biblioteca como prettytable o descargar pandas o algo así, pero no estoy muy interesado en hacer eso.
Solo quiero generar mis filas como tablas en la celda de mi cuaderno Jupyter. ¿Cómo hago esto?
python
jupyter-notebook
Wayne Werner
fuente
fuente
print
funciones? Son los números fijos de ancho (1 dígito, tres dígitos?Respuestas:
Acabo de descubrir que tabular tiene una opción HTML y es bastante simple de usar.
Muy similar a la respuesta de Wayne Werner:
from IPython.display import HTML, display import tabulate table = [["Sun",696000,1989100000], ["Earth",6371,5973.6], ["Moon",1737,73.5], ["Mars",3390,641.85]] display(HTML(tabulate.tabulate(table, tablefmt='html')))
Sigo buscando algo simple de usar para crear diseños de tablas más complejos, como la sintaxis de látex y el formato para fusionar celdas y hacer sustitución de variables en un cuaderno:
Permita referencias a variables de Python en celdas de Markdown # 2958
fuente
tabulate.tabulate(table, tablefmt='html')
parece funcionar (probé Jupyter 6.0.3, JupyterLab 2.0.1). ¡Agradable!Hay un buen truco: envuelve los datos con pandas DataFrame.
import pandas as pd data = [[1, 2], [3, 4]] pd.DataFrame(data, columns=["Foo", "Bar"])
Muestra datos como:
| Foo | Bar | 0 | 1 | 2 | 1 | 3 | 4 |
fuente
to_html()
, consulte stackoverflow.com/a/29665452/2866660Finalmente encontré la documentación de jupyter / IPython que estaba buscando.
Necesitaba esto:
from IPython.display import HTML, display data = [[1,2,3], [4,5,6], [7,8,9], ] display(HTML( '<table><tr>{}</tr></table>'.format( '</tr><tr>'.join( '<td>{}</td>'.format('</td><td>'.join(str(_) for _ in row)) for row in data) ) ))
(Puede que haya estropeado un poco las comprensiones, pero
display(HTML('some html here'))
es lo que necesitábamos)fuente
tabletext encaja bien
import tabletext data = [[1,2,30], [4,23125,6], [7,8,999], ] print tabletext.to_text(data)
resultado:
┌───┬───────┬─────┐ │ 1 │ 2 │ 30 │ ├───┼───────┼─────┤ │ 4 │ 23125 │ 6 │ ├───┼───────┼─────┤ │ 7 │ 8 │ 999 │ └───┴───────┴─────┘
fuente
Si no le importa usar un poco de html, algo como esto debería funcionar.
from IPython.display import HTML, display def display_table(data): html = "<table>" for row in data: html += "<tr>" for field in row: html += "<td><h4>%s</h4><td>"%(field) html += "</tr>" html += "</table>" display(HTML(html))
Y luego úsalo así
data = [[1,2,3],[4,5,6],[7,8,9]] display_table(data)
fuente
Puedes intentar usar la siguiente función
def tableIt(data): for lin in data: print("+---"*len(lin)+"+") for inlin in lin: print("|",str(inlin),"", end="") print("|") print("+---"*len(lin)+"+") data = [[1,2,3,2,3],[1,2,3,2,3],[1,2,3,2,3],[1,2,3,2,3]] tableIt(data)
fuente
Ok, esto fue un poco más difícil de lo que pensé:
def print_matrix(list_of_list): number_width = len(str(max([max(i) for i in list_of_list]))) cols = max(map(len, list_of_list)) output = '+'+('-'*(number_width+2)+'+')*cols + '\n' for row in list_of_list: for column in row: output += '|' + ' {:^{width}d} '.format(column, width = number_width) output+='|\n+'+('-'*(number_width+2)+'+')*cols + '\n' return output
Esto debería funcionar para un número variable de filas, columnas y número de dígitos (para números)
data = [[1,2,30], [4,23125,6], [7,8,999], ] print print_matrix(data) >>>>+-------+-------+-------+ | 1 | 2 | 30 | +-------+-------+-------+ | 4 | 23125 | 6 | +-------+-------+-------+ | 7 | 8 | 999 | +-------+-------+-------+
fuente
Un conjunto de funciones de propósito general para representar cualquier estructura de datos de Python (dictados y listas anidadas juntas) como HTML.
from IPython.display import HTML, display def _render_list_html(l): o = [] for e in l: o.append('<li>%s</li>' % _render_as_html(e)) return '<ol>%s</ol>' % ''.join(o) def _render_dict_html(d): o = [] for k, v in d.items(): o.append('<tr><td>%s</td><td>%s</td></tr>' % (str(k), _render_as_html(v))) return '<table>%s</table>' % ''.join(o) def _render_as_html(e): o = [] if isinstance(e, list): o.append(_render_list_html(e)) elif isinstance(e, dict): o.append(_render_dict_html(e)) else: o.append(str(e)) return '<html><body>%s</body></html>' % ''.join(o) def render_as_html(e): display(HTML(_render_as_html(e)))
fuente
Yo solia tener el mismo problema. No pude encontrar nada que me ayudara, así que terminé haciendo la clase:
PrintTable
código a continuación. También hay una salida. El uso es simple:o en una línea:
Salida:
------------------------------------------------------------------------------------------------------------- Name | Column 1 | Column 2 | Column 3 | Column 4 | Column 5 ------------------------------------------------------------------------------------------------------------- Very long name 0 | 0 | 0 | 0 | 0 | 0 Very long name 1 | 1 | 2 | 3 | 4 | 5 Very long name 2 | 2 | 4 | 6 | 8 | 10 Very long name 3 | 3 | 6 | 9 | 12 | 15 Very long name 4 | 4 | 8 | 12 | 16 | 20 Very long name 5 | 5 | 10 | 15 | 20 | 25 Very long name 6 | 6 | 12 | 18 | 24 | 30 Very long name 7 | 7 | 14 | 21 | 28 | 35 Very long name 8 | 8 | 16 | 24 | 32 | 40 Very long name 9 | 9 | 18 | 27 | 36 | 45 Very long name 10 | 10 | 20 | 30 | 40 | 50 Very long name 11 | 11 | 22 | 33 | 44 | 55 Very long name 12 | 12 | 24 | 36 | 48 | 60 Very long name 13 | 13 | 26 | 39 | 52 | 65 Very long name 14 | 14 | 28 | 42 | 56 | 70 Very long name 15 | 15 | 30 | 45 | 60 | 75 Very long name 16 | 16 | 32 | 48 | 64 | 80 Very long name 17 | 17 | 34 | 51 | 68 | 85 Very long name 18 | 18 | 36 | 54 | 72 | 90 Very long name 19 | 19 | 38 | 57 | 76 | 95 -------------------------------------------------------------------------------------------------------------
El código de la clase
PrintTable
# -*- coding: utf-8 -*- # Class class PrintTable: def __init__(self, values, captions, widths, aligns): if not all([len(values[0]) == len(x) for x in [captions, widths, aligns]]): raise Exception() self._tablewidth = sum(widths) + 3*(len(captions)-1) + 4 self._values = values self._captions = captions self._widths = widths self._aligns = aligns def print(self): self._printTable() def _printTable(self): formattext_head = "" formattext_cell = "" for i,v in enumerate(self._widths): formattext_head += "{" + str(i) + ":<" + str(v) + "} | " formattext_cell += "{" + str(i) + ":" + self._aligns[i] + str(v) + "} | " formattext_head = formattext_head[:-3] formattext_head = " " + formattext_head.strip() + " " formattext_cell = formattext_cell[:-3] formattext_cell = " " + formattext_cell.strip() + " " print("-"*self._tablewidth) print(formattext_head.format(*self._captions)) print("-"*self._tablewidth) for w in self._values: print(formattext_cell.format(*w)) print("-"*self._tablewidth)
Demostración
# Demonstration headername = ["Column {}".format(x) for x in range(6)] headername[0] = "Name" data = [["Very long name {}".format(x), x, x*2, x*3, x*4, x*5] for x in range(20)] PrintTable(data, \ headername, \ [70, 10, 10, 10, 10, 10], \ ["<",">",">",">",">",">"]).print()
fuente
Recientemente utilicé
prettytable
para renderizar una bonita tabla ASCII. Es similar a la salida CLI de postgres.import pandas as pd from prettytable import PrettyTable data = [[1,2,3],[4,5,6],[7,8,9]] df = pd.DataFrame(data, columns=['one', 'two', 'three']) def generate_ascii_table(df): x = PrettyTable() x.field_names = df.columns.tolist() for row in df.values: x.add_row(row) print(x) return x generate_ascii_table(df)
Salida:
+-----+-----+-------+ | one | two | three | +-----+-----+-------+ | 1 | 2 | 3 | | 4 | 5 | 6 | | 7 | 8 | 9 | +-----+-----+-------+
fuente
Quiero generar una tabla donde cada columna tiene el ancho más pequeño posible, donde las columnas se rellenan con espacios en blanco (pero esto se puede cambiar) y las filas están separadas por líneas nuevas (pero esto se puede cambiar) y donde cada elemento se formatea usando
str
( pero...).def ftable(tbl, pad=' ', sep='\n', normalize=str): # normalize the content to the most useful data type strtbl = [[normalize(it) for it in row] for row in tbl] # next, for each column we compute the maximum width needed w = [0 for _ in tbl[0]] for row in strtbl: for ncol, it in enumerate(row): w[ncol] = max(w[ncol], len(it)) # a string is built iterating on the rows and the items of `strtbl`: # items are prepended white space to an uniform column width # formatted items are `join`ed using `pad` (by default " ") # eventually we join the rows using newlines and return return sep.join(pad.join(' '*(wid-len(it))+it for wid, it in zip(w, row)) for row in strtbl)
La firma de la función
ftable(tbl, pad=' ', sep='\n', normalize=str)
, con sus argumentos predeterminados está destinada a proporcionar la máxima flexibilidad.Puedes personalizar
pad='&', sep='\\\\\n'
para tener la mayor parte de una mesa de látex)str
pero si sabe que todos sus datos son de punto flotantelambda item: "%.4f"%item
podría ser una opción razonable, etc.Pruebas superficiales:
Necesito algunos datos de prueba, posiblemente involucrando columnas de diferente ancho para que el algoritmo deba ser un poco más sofisticado (pero solo un poco;)
In [1]: from random import randrange In [2]: table = [[randrange(10**randrange(10)) for i in range(5)] for j in range(3)] In [3]: table Out[3]: [[974413992, 510, 0, 3114, 1], [863242961, 0, 94924, 782, 34], [1060993, 62, 26076, 75832, 833174]] In [4]: print(ftable(table)) 974413992 510 0 3114 1 863242961 0 94924 782 34 1060993 62 26076 75832 833174 In [5]: print(ftable(table, pad='|')) 974413992|510| 0| 3114| 1 863242961| 0|94924| 782| 34 1060993| 62|26076|75832|833174
fuente