Wie gebe ich Listen als Tabelle in Jupyter Notebook aus?

80

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

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 Stettytable verwenden oder Pandas oder ähnliches herunterladen, aber ich bin sehr desinteressiert daran.

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

Wayne Werner
quelle
Möchten Sie nur printFunktionen verwenden? Sind die Zahlen in der Breite festgelegt (1 Ziffer, drei Ziffern?
Tglaria
Hier habe ich pythonische Abstraktion geschrieben. Code ohne Probleme. :) jupyter_table_class.py
not_python

Antworten:

84

Ich habe gerade festgestellt, dass tabulate eine HTML-Option hat und ziemlich einfach zu verwenden 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 immer noch nach etwas Einfachem, um komplexere Tabellenlayouts zu erstellen, z. B. mit Latexsyntax und Formatierung, um Zellen zusammenzuführen und Variablen in einem Notizbuch zu ersetzen:
Erlauben Sie Verweise auf Python-Variablen in Markdown-Zellen # 2958

ruffsl
quelle
Das Ausrichten von Saiten hat bei mir nicht funktioniert! Die Zeichenfolge wird nicht nach links ausgerichtet!
Mojtaba Khodadadi
@MojtabaKhodadadi überprüft es nicht genau, aber es sieht aus wie Sie die Standard - Spalten Argument für srtings vs Zahlen festlegen hier .
Ruffsl
Heutzutage tabulate.tabulate(table, tablefmt='html')scheint es sogar nur zu funktionieren (versucht Jupyter 6.0.3, JupyterLab 2.0.1). Nett!
Zonksoft
80

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   |
Anton Dergunov
quelle
13
Als jemand, der Python für alles, ABER für die Datenwissenschaft, absolut liebt, macht es mich WIRKLICH traurig zu sehen, dass Anrufantworten mit neun Zeilen, vierfachem Import und dreifacher Funktion bewertet werden, wenn die am besten aussehende Antwort buchstäblich "ein Pandas-Datenrahmen" ist. Meine Heuristik lautet: "Wenn es lang ist - ist es wahrscheinlich falsch!"
one_observation
1
Sie können den DataFrame sogar als HTML mit anzeigento_html() , siehe stackoverflow.com/a/29665452/2866660
wvengen
Vielen Dank! Ja, die akzeptierte Antwort sollte definitiv in diese geändert werden.
Helen
58

Endlich habe ich die gesuchte Jupyter / IPython-Dokumentation 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 durcheinander gebracht, aber display(HTML('some html here'))wir haben es gebraucht)

Wayne Werner
quelle
12

Tabletext passt gut dazu

import tabletext

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

print tabletext.to_text(data)

Ergebnis:

┌───┬───────┬─────┐
│ 1230 │
├───┼───────┼─────┤
│ 4231256 │
├───┼───────┼─────┤
│ 78999 │
└───┴───────┴─────┘
Nummer 5
quelle
4

Wenn es Ihnen nichts ausmacht, ein bisschen HTML zu verwenden, sollte so etwas funktionieren.

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

Und dann benutze es so

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

Geben Sie hier die Bildbeschreibung ein

Satyajit
quelle
2

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)
Taoufik BELKEBIR
quelle
2

Ok, das war etwas schwieriger als ich:

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 die variable Anzahl von Zeilen, Spalten und die Anzahl der 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  |
    +-------+-------+-------+
Tglaria
quelle
1

Ein allgemeiner Funktionssatz zum Rendern einer beliebigen Python-Datenstruktur (Dicts und Listen, die zusammen verschachtelt sind) 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)))
Am schwierigsten
quelle
1

Ich hatte früher das gleiche Problem. Ich konnte nichts finden, was mir helfen würde, also machte ich den PrintTableKlassencode unten. 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()
Celdor
quelle
1

Ich habe kürzlich prettytableeine schöne ASCII-Tabelle gerendert. 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   |
+-----+-----+-------+
AlexG
quelle
0

Ich möchte eine Tabelle ausgeben, in der jede Spalte die kleinstmögliche Breite hat, in der Spalten mit Leerzeichen aufgefüllt sind (dies kann jedoch geändert werden) und Zeilen durch Zeilenumbrüche getrennt werden (dies kann jedoch geändert werden) und in der jedes Element mit str( formatiert wird) formatiert wird . 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 maximale Flexibilität bieten.

Sie können anpassen

  • die Spalten pad ding,
  • der Zeile September arator, (beispielsweise pad='&', sep='\\\\\n'die Masse einer Latex - Tabelle haben)
  • Die Funktion, mit der die Eingabe auf ein gemeinsames Zeichenfolgenformat normalisiert wird - standardmäßig für die maximale Allgemeinheit. strWenn Sie jedoch wissen, dass alle Ihre Daten Gleitkommawerte sind, lambda item: "%.4f"%itemkann dies eine vernünftige Wahl sein.

Oberflächliche Prüfung:

Ich benötige einige Testdaten, möglicherweise mit Spalten unterschiedlicher Breite, damit der Algorithmus etwas ausgefeilter 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
gboffi
quelle