webentwicklung-frage-antwort-db.com.de

Wie gebe ich Listen als Tabelle in einem Jupyter-Notizbuch aus?

Ich weiß, dass ich irgendwo ein Beispiel gesehen habe, aber für mein Leben kann ich es beim Googeln nicht finden.

Ich habe einige Datenzeilen:

data = [[1,2,3],
        [4,5,6],
        [7,8,9],
        ]

Und ich möchte diese Daten in einer Tabelle ausgeben, z.

+---+---+---+
| 1 | 2 | 3 |
+---+---+---+
| 4 | 5 | 6 |
+---+---+---+
| 7 | 8 | 9 |
+---+---+---+

Natürlich könnte ich eine Bibliothek wie prettytable verwenden, Pandas herunterladen oder so, aber ich habe kein großes Interesse daran.

Ich möchte nur meine Zeilen als Tabellen in meiner Jupyter-Notebookzelle ausgeben. Wie mache ich das?

49
Wayne Werner

Endlich habe ich die jupyter/IPython-Dokumentation nach der ich gesucht habe, wiedergefunden.

Ich brauchte das:

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)
       )
))

(Ich habe vielleicht das Verständnis etwas aufgemischt, aber display(HTML('some html here')) ist das, was wir brauchten)

41
Wayne Werner

Ich habe gerade entdeckt, dass tabulate eine HTML-Option hat und ziemlich einfach zu bedienen ist.
Ganz ähnlich wie Wayne Werners Antwort:

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')))

Suchen Sie nach etwas Einfachem, das Sie verwenden können, um komplexere Tabellenlayouts zu erstellen, z. B. mit Latex-Syntax und Formatierung, um Zellen zusammenzuführen und Variablen in einem Notizbuch zu ersetzen:
Erlaube Verweise auf Python-Variablen in Markdown-Zellen # 2958

47
ruffsl

Es gibt einen schönen Trick: Wickeln Sie die Daten mit Pandas DataFrame.

import pandas as pd
data = [[1, 2], [3, 4]]
pd.DataFrame(data, columns=["Foo", "Bar"])

Es zeigt Daten wie:

  | Foo | Bar |
0 | 1   | 2   |
1 | 3   | 4   |
24
Anton Dergunov

tabletext passt gut dazu

import tabletext

data = [[1,2,30],
        [4,23125,6],
        [7,8,999],
        ]

print tabletext.to_text(data)

ergebnis:

┌───┬───────┬─────┐
│ 1 │     2 │  30 │
├───┼───────┼─────┤
│ 4 │ 23125 │   6 │
├───┼───────┼─────┤
│ 7 │     8 │ 999 │
└───┴───────┴─────┘
6
number5

Ok, das war etwas schwieriger als ich dachte:

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

Dies sollte für variable Anzahl von Zeilen, Spalten und Anzahl von Ziffern (für Zahlen) funktionieren.

data = [[1,2,30],
        [4,23125,6],
        [7,8,999],
        ]
print print_matrix(data)
>>>>+-------+-------+-------+
    |   1   |   2   |  30   |
    +-------+-------+-------+
    |   4   | 23125 |   6   |
    +-------+-------+-------+
    |   7   |   8   |  999  |
    +-------+-------+-------+
2
tglaria

Ein allgemeiner Funktionssatz zum Rendern von Python-Datenstrukturen (verschachtelten Diktaten und Listen) als 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)))
2
Hardest

Sie können versuchen, die folgende Funktion zu verwenden

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)
2

Ich hatte früher das gleiche Problem. Ich konnte nichts finden, was mir helfen würde, also machte ich am Ende den Klassencode PrintTable--. Es gibt auch eine Ausgabe. Die Verwendung ist einfach:

ptobj = PrintTable(yourdata, column_captions, column_widths, text_aligns)
ptobj.print()

oder in einer Zeile:

PrintTable(yourdata, column_captions, column_widths, text_aligns).print()

Ausgabe:

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

Der Code für die Klasse 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)

Demonstration

# 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()
1
Celdor

Ich möchte eine Tabelle ausgeben, in der jede Spalte die kleinstmögliche Breite hat, Wobei Spalten mit Leerzeichen aufgefüllt werden (dies kann jedoch geändert werden) und Zeilen durch Zeilenumbrüche getrennt werden (dies kann jedoch geändert werden) und wo sich die einzelnen Elemente befinden formatiert mit str (aber ...).


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)

Die Funktionssignatur ftable(tbl, pad=' ', sep='\n', normalize=str) mit ihren Standardargumenten soll Für maximale Flexibilität sorgen.

Sie können anpassen

  • die Spalte pad Ding,
  • die Zeile sep arator (z. B. pad='&', sep='\\\\\n', um den Großteil einer LaTeX-Tabelle zu erhalten)
  • die Funktion, die verwendet werden soll, um normalize die Eingabe in eine allgemeine Zeichenfolge format --- zu übernehmen. Standardmäßig ist dies str, aber wenn Sie wissen, dass alle Ihre Daten vorhanden sind Gleitkomma lambda item: "%.4f"%item könnte eine vernünftige Wahl sein usw.

Oberflächliche Prüfung:

Ich brauche einige Testdaten, möglicherweise mit Spalten unterschiedlicher Breite Damit der Algorithmus ein wenig komplexer sein muss (aber nur ein bisschen;)

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

Hier habe ich Pythonic-Abstraktion geschrieben. Code ohne Ärger. :) 

jupyter_table_class.py

0
crook

Ich habe kürzlich prettytable zum Rendern einer Nice ASCII -Tabelle verwendet. Es ähnelt der Postgres-CLI-Ausgabe.

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)

Ausgabe:

+-----+-----+-------+
| one | two | three |
+-----+-----+-------+
|  1  |  2  |   3   |
|  4  |  5  |   6   |
|  7  |  8  |   9   |
+-----+-----+-------+
0
AlexG