Python 如何在 Jupyter 笔记本中将列表输出为表格?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35160256/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 16:04:12  来源:igfitidea点击:

How do I output lists as a table in Jupyter notebook?

pythonjupyter-notebook

提问by Wayne Werner

I know that I've seen some example somewhere before but for the life of me I cannot find it when googling around.

我知道我以前在某处见过一些例子,但对于我的生活,我在谷歌搜索时找不到它。

I have some rows of data:

我有几行数据:

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

And I want to output this data in a table, e.g.

我想在表格中输出这些数据,例如

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

Obviously I could use a library like prettytable or download pandas or something but I'm very disinterested in doing that.

显然我可以使用一个像prettytable 这样的库或者下载pandas 之类的,但我对这样做很不感兴趣。

I just want to output my rows as tables in my Jupyter notebook cell. How do I do this?

我只想在我的 Jupyter 笔记本单元格中将我的行输出为表格。我该怎么做呢?

采纳答案by Wayne Werner

I finally re-found the jupyter/IPython documentationthat I was looking for.

我终于重新找到了我正在寻找的jupyter/IPython 文档

I needed this:

我需要这个:

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

(I may have slightly mucked up the comprehensions, but display(HTML('some html here'))is what we needed)

(我可能稍微搞砸了理解,但这display(HTML('some html here'))是我们需要的)

回答by Taoufik BELKEBIR

You could try to use the following function

您可以尝试使用以下功能

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)

回答by tglaria

Ok, so this was a bit harder than I though:

好的,所以这比我更难:

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

This should work for variable number of rows, columns and number of digits (for numbers)

这应该适用于可变数量的行、列和位数(对于数字)

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

回答by number5

tabletextfit this well

表格文本很适合这个

import tabletext

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

print tabletext.to_text(data)

result:

结果:

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

回答by ruffsl

I just discovered that tabulatehas a HTML option and is rather simple to use.
Quite similar to Wayne Werner's answer:

我刚刚发现tabulate有一个 HTML 选项并且使用起来相当简单。
与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')))

Still looking for something simple to use to create more complex table layouts like with latex syntax and formatting to merge cells and do variable substitution in a notebook:
Allow references to Python variables in Markdown cells #2958

仍在寻找一些简单易用的东西来创建更复杂的表格布局,例如使用 Latex 语法和格式来合并单元格并在笔记本中进行变量替换:
允许在 Markdown 单元格中引用 Python 变量 #2958

回答by Hardest

A general purpose set of functions to render any python data structure (dicts and lists nested together) as HTML.

将任何 Python 数据结构(嵌套在一起的字典和列表)呈现为 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)))

回答by Celdor

I used to have the same problem. I could not find anything that would help me so I ended up making the class PrintTable--code below. There is also an output. The usage is simple:

我曾经有同样的问题。我找不到任何对我有帮助的东西,所以我最终制作了PrintTable下面的类--code。还有一个输出。用法很简单:

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

or in one line:

或在一行中:

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

Output:

输出:

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

The code for the class PrintTable

类的代码 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()

回答by gboffi

I want to output a table where each column has the smallest possible width, where columns are padded with white space (but this can be changed) and rows are separated by newlines (but this can be changed) and where each item is formatted using str(but...).

我想输出一个表格,其中每一列的宽度尽可能小,列用空格填充(但这可以更改),行之间用换行符分隔(但可以更改),并且每个项目都使用str(但...)。



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)

The function signature, ftable(tbl, pad=' ', sep='\n', normalize=str), with its default arguments is intended to provide for maximum flexibility.

ftable(tbl, pad=' ', sep='\n', normalize=str)带有默认参数的函数签名旨在提供最大的灵活性。

You can customize

您可以自定义

  • the column padding,
  • the row separator, (e.g., pad='&', sep='\\\\\n'to have the bulk of a LaTeX table)
  • the function to be used to normalizethe input to a common string format --- by default, for the maximum generality it is strbut if you know that all your data is floating point lambda item: "%.4f"%itemcould be a reasonable choice, etc.
  • 丁,
  • arator,(例如,pad='&', sep='\\\\\n'以具有一个散装乳胶表的)
  • 用于将输入规范化为通用字符串格式的函数--- 默认情况下,为了最大的通用性,str但如果您知道所有数据都是浮点数,则lambda item: "%.4f"%item可能是一个合理的选择,等等。


Superficial testing:

表面测试:

I need some test data, possibly involving columns of different width so that the algorithm needs to be a little more sophisticated (but just a little bit;)

我需要一些测试数据,可能涉及不同宽度的列,因此算法需要更复杂一点(但只是一点点;)

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

回答by Anton Dergunov

There is a nice trick: wrap the data with pandas DataFrame.

有一个很好的技巧:用pandas DataFrame 包装数据。

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

It displays data like:

它显示如下数据:

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

回答by AlexG

I recently used prettytablefor rendering a nice ASCII table. It's similar to the postgres CLI output.

我最近用来prettytable渲染一个漂亮的 ASCII 表。它类似于 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)

Output:

输出:

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