Làm cách nào để xuất danh sách dưới dạng bảng trong sổ ghi chép Jupyter?


80

Tôi biết rằng tôi đã nhìn thấy một số ví dụ ở đâu đó trước đây nhưng đối với cuộc sống của tôi, tôi không thể tìm thấy nó khi googling xung quanh.

Tôi có một số hàng dữ liệu:

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

Và tôi muốn xuất dữ liệu này trong một bảng, ví dụ:

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

Rõ ràng là tôi có thể sử dụng một thư viện như prettytable hoặc tải về gấu trúc hoặc thứ gì đó nhưng tôi rất không thích làm điều đó.

Tôi chỉ muốn xuất các hàng của mình dưới dạng bảng trong ô sổ ghi chép Jupyter của tôi. Làm thế nào để tôi làm điều này?


Bạn có muốn chỉ sử dụng các printchức năng không? Các số có chiều rộng cố định không (1 chữ số, 3 chữ số?
tglaria

Ở đây tôi đã viết trừu tượng con trăn. Mã không có rắc rối. :) jupyter_table_class.py
not_python

Câu trả lời:


85

Tôi vừa phát hiện ra rằng lập bảng có một tùy chọn HTML và khá đơn giản để sử dụng.
Khá giống với câu trả lời của 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')))

Vẫn đang tìm kiếm thứ gì đó đơn giản để sử dụng để tạo bố cục bảng phức tạp hơn như với cú pháp latex và định dạng để hợp nhất các ô và thực hiện thay thế biến trong sổ tay:
Cho phép tham chiếu đến các biến Python trong ô Markdown # 2958


Căn chỉnh các chuỗi không hoạt động với tôi! Nó không căn chỉnh chuỗi bên trái!
Mojtaba Khodadadi

@MojtabaKhodadadi chưa kiểm tra kỹ nhưng có vẻ như bạn có thể đặt đối số cột mặc định cho srtings so với số tại đây .
ruffsl

Ngày nay thậm chí tabulate.tabulate(table, tablefmt='html')dường như chỉ hoạt động (đã thử Jupyter 6.0.3, JupyterLab 2.0.1). Đẹp!
zonksoft

82

Có một mẹo hay: bọc dữ liệu bằng DataFrame của gấu trúc.

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

Nó hiển thị dữ liệu như:

  | Foo | Bar |
0 | 1   | 2   |
1 | 3   | 4   |

14
Là một người hoàn toàn yêu thích python cho mọi thứ NHƯNG khoa học dữ liệu, điều đó khiến tôi THỰC SỰ buồn khi thấy các câu trả lời gọi hàm chín dòng, nhập bốn lần, ba chức năng được bình chọn khi câu trả lời TỐT NHẤT theo nghĩa đen là "một con gấu trúc DataFrame." Kinh nghiệm của tôi là: "Nếu nó dài - nó có thể là sai!"
one_observation

1
Bạn thậm chí có thể hiển thị DataFrame dưới dạng HTML bằng cách sử dụng to_html(), xem stackoverflow.com/a/29665452/2866660
wvengen

Cảm ơn! Có, câu trả lời được chấp nhận chắc chắn nên được thay đổi thành câu trả lời này.
Helen

59

Cuối cùng tôi đã tìm lại được tài liệu jupyter / IPython mà tôi đang tìm kiếm.

Tôi cần cái này:

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

(Tôi có thể đã hiểu sai một chút, nhưng đó display(HTML('some html here'))là những gì chúng tôi cần)


13

tabletext phù hợp với điều này

import tabletext

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

print tabletext.to_text(data)

kết quả:

┌───┬───────┬─────┐
│ 1230 │
├───┼───────┼─────┤
│ 4231256 │
├───┼───────┼─────┤
│ 78999 │
└───┴───────┴─────┘

4

Nếu bạn không phiền khi sử dụng một chút html, một cái gì đó như thế này sẽ hoạt động.

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

Và sau đó sử dụng nó như thế này

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

nhập mô tả hình ảnh ở đây


2

Bạn có thể thử sử dụng chức năng sau

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

Ok, vì vậy điều này khó hơn một chút so với tôi:

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

Điều này sẽ hoạt động đối với số lượng hàng, cột và số chữ số thay đổi (đối với số)

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

1

Một tập hợp các chức năng có mục đích chung để hiển thị bất kỳ cấu trúc dữ liệu python nào (các đoạn và danh sách được lồng vào nhau) dưới dạng 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)))

1

Tôi đã từng có cùng một vấn đề. Tôi không thể tìm thấy bất kỳ điều gì có thể giúp mình nên tôi đã kết thúc việc tạo lớp - PrintTablemã bên dưới. Cũng có một đầu ra. Cách sử dụng rất đơn giản:

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

hoặc trong một dòng:

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

Đầu ra:

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

Mã cho lớp học 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)

Trình diễ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()

1

Gần đây tôi đã sử dụng prettytableđể hiển thị một bảng ASCII đẹp. Nó tương tự như đầu ra CLI 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)

Đầu ra:

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

0

Tôi muốn xuất một bảng trong đó mỗi cột có chiều rộng nhỏ nhất có thể, trong đó các cột được đệm bằng khoảng trắng (nhưng điều này có thể được thay đổi) và các hàng được phân tách bằng dòng mới (nhưng điều này có thể được thay đổi) và nơi mỗi mục được định dạng bằng str( nhưng...).


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)

Chữ ký hàm ftable(tbl, pad=' ', sep='\n', normalize=str), với các đối số mặc định của nó nhằm cung cấp tính linh hoạt tối đa.

Bạn có thể tùy chỉnh

  • đệm cột ding,
  • arator sep hàng , (ví dụ: pad='&', sep='\\\\\n'để có phần lớn bảng LaTeX)
  • hàm được sử dụng để chuẩn hóa đầu vào thành một định dạng chuỗi chung --- theo mặc định, để có tính tổng quát tối đa strnhưng nếu bạn biết rằng tất cả dữ liệu của mình là dấu phẩy động lambda item: "%.4f"%itemcó thể là một lựa chọn hợp lý, v.v.

Kiểm tra bề ngoài:

Tôi cần một số dữ liệu thử nghiệm, có thể liên quan đến các cột có độ rộng khác nhau để thuật toán cần phức tạp hơn một chút (nhưng chỉ một chút thôi;)

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.