Jak wyświetlić listy jako tabelę w notatniku Jupyter?

80

Wiem, że gdzieś już widziałem jakiś przykład, ale przez całe życie nie mogę go znaleźć, szukając go w Google.

Mam kilka wierszy danych:

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

I chcę wyprowadzić te dane w tabeli np

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

Oczywiście mógłbym użyć biblioteki takiej jak prettytable lub pobrać pandy lub coś w tym stylu, ale jestem tym bardzo bezinteresowna.

Chcę tylko wyprowadzić moje wiersze jako tabele w mojej komórce notesu Jupyter. Jak mam to zrobic?

Wayne Werner
źródło
Czy chcesz używać tylko printfunkcji? Czy liczby mają stałą szerokość (1 cyfra, trzy cyfry?
tglaria
Tutaj napisałem pythonową abstrakcję. Kod bez kłopotów. :) jupyter_table_class.py
not_python

Odpowiedzi:

85

Właśnie odkryłem, że tabulate ma opcję HTML i jest raczej prosty w użyciu.
Całkiem podobne do odpowiedzi Wayne'a Wernera:

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

Wciąż szukam czegoś prostego w użyciu do tworzenia bardziej złożonych układów tabel, takich jak składnia lateksowa i formatowanie w celu scalania komórek i podstawiania zmiennych w notatniku:
Zezwalaj na odwołania do zmiennych Pythona w komórkach Markdown # 2958

ruffl
źródło
Wyrównywanie strun nie działa dla mnie! Nie wyrównuje łańcucha do lewej!
Mojtaba Khodadadi
@MojtabaKhodadadi nie sprawdziłem go dokładnie, ale wygląda na to, można ustawić domyślny kolumny argument srtings vs numery tutaj .
ruffsl
W dzisiejszych czasach nawet tabulate.tabulate(table, tablefmt='html')wydaje się, że działa (wypróbowałem Jupyter 6.0.3, JupyterLab 2.0.1). Miły!
zonksoft
82

Jest fajna sztuczka: zawijaj dane pandami DataFrame.

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

Wyświetla dane takie jak:

  | Foo | Bar |
0 | 1   | 2   |
1 | 3   | 4   |
Anton Dergunov
źródło
14
Jako ktoś, kto absolutnie kocha Pythona za wszystko, ALE naukę o danych, NAPRAWDĘ smutno mi widzieć dziewięcioliniowe, poczwórne importowane i potrójne funkcje wywołania, które są głosowane, gdy NAJLEPSZA odpowiedź brzmi dosłownie „pandy DataFrame”. Moja heurystyka brzmi: „Jeśli jest długi - prawdopodobnie jest zły!”
one_observation,
1
Możesz nawet wyświetlić ramkę DataFrame jako HTML, używając to_html(), patrz stackoverflow.com/a/29665452/2866660
wvengen
Dzięki! Tak, zaakceptowaną odpowiedź zdecydowanie należy zmienić na tę.
Helen
59

W końcu ponownie znalazłem dokumentację jupyter / IPython , której szukałem.

Potrzebowałem tego:

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

(Może trochę zawiodłem rozumowanie, ale display(HTML('some html here'))tego potrzebowaliśmy)

Wayne Werner
źródło
13

tabletext dobrze do tego pasuje

import tabletext

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

print tabletext.to_text(data)

wynik:

┌───┬───────┬─────┐
│ 1230 │
├───┼───────┼─────┤
│ 4231256 │
├───┼───────┼─────┤
│ 78999 │
└───┴───────┴─────┘
numer 5
źródło
4

Jeśli nie masz nic przeciwko używaniu trochę HTML, coś takiego powinno działać.

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

A potem użyj tego w ten sposób

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

wprowadź opis obrazu tutaj

Satyajit
źródło
2

Możesz spróbować użyć następującej funkcji

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
źródło
2

Ok, więc to było trochę trudniejsze niż myślałem:

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

To powinno działać dla zmiennej liczby wierszy, kolumn i liczby cyfr (dla liczb)

data = [[1,2,30],
        [4,23125,6],
        [7,8,999],
        ]
print print_matrix(data)
>>>>+-------+-------+-------+
    |   1   |   2   |  30   |
    +-------+-------+-------+
    |   4   | 23125 |   6   |
    +-------+-------+-------+
    |   7   |   8   |  999  |
    +-------+-------+-------+
tglaria
źródło
1

Zestaw funkcji ogólnego przeznaczenia do renderowania dowolnej struktury danych Pythona (dykty i listy zagnieżdżone razem) jako 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)))
Najtrudniejsze
źródło
1

Miałem kiedyś ten sam problem. Nie mogłem znaleźć niczego, co by mi pomogło, więc PrintTableutworzyłem poniższy kod zajęć . Jest też wyjście. Użycie jest proste:

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

lub w jednej linii:

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

Wynik:

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

Kod zajęć 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)

Demonstracja

# 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
źródło
1

Niedawno użyłem prettytabledo renderowania ładnej tabeli ASCII. Jest podobny do wyjścia postgres CLI.

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)

Wynik:

+-----+-----+-------+
| one | two | three |
+-----+-----+-------+
|  1  |  2  |   3   |
|  4  |  5  |   6   |
|  7  |  8  |   9   |
+-----+-----+-------+
AlexG
źródło
0

Chcę wyprowadzić tabelę, w której każda kolumna ma najmniejszą możliwą szerokość, w której kolumny są wypełnione spacjami (ale można to zmienić), a wiersze są oddzielone znakami nowej linii (ale można to zmienić) i gdzie każdy element jest formatowany przy użyciu str( ale...).


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)

Podpis funkcji ftable(tbl, pad=' ', sep='\n', normalize=str)z domyślnymi argumentami ma na celu zapewnienie maksymalnej elastyczności.

Możesz dostosować

  • kolumna pad,
  • rząd września Arator (na przykładpad='&', sep='\\\\\n'mieć masę stołu lateks)
  • funkcja, która ma być używana do normalizowania danych wejściowych do wspólnego formatu ciągu --- domyślnie, dla maksymalnego uogólnieniastr ale jeśli wiesz, że wszystkie dane są zmiennoprzecinkowe, lambda item: "%.4f"%itemmoże być rozsądnym wyborem itp.

Powierzchowne testy:

Potrzebuję danych testowych, być może obejmujących kolumny o różnej szerokości, aby algorytm musiał być nieco bardziej wyrafinowany (ale tylko trochę;)

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
źródło