[Python]tabulateを使って様々な形式の表を作る

Pythonで様々なフォーマットの表を作成するのに便利なパッケージのtabulateの使い方を説明します。 tabulateを使えばMarkdownやHTML、CLI向けなどの様々な形式で表をつくれます。
2021.07.07

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

tabulateとは

tabulateはPythonで表を表示するためのパッケージです。 MarkdownやHTML、LaTexなど様々な形式に対応しているので分析の結果をレポートにまとめたい時などに便利です。 Pythonで一気に表の作成まで行ってしまえば手作業で表を作る必要がなくなります。

使い方

インストール

pipを使用すれば以下のようにインストールできます。

インストール

pip3 install tabulate

以下では次のようにインポートして使用していきます。

インポート

>>> from tabulate import tabulate

扱えるデータ

tabulateでは入力データとして様々な形式のデータが扱えます。 今回は例として以下の三つを見てみましょう。 他にもNumPyやPandasの形式も使用できます。

行のリスト(タプルまたはリスト)

行のリスト

>>> data = [
...     (0, 'foo', 25),
...     (1, 'bar', 32),
...     (2, 'baz', 59),
... ]
>>> print(tabulate(data))
-  ---  --
0  foo  25
1  bar  32
2  baz  59
-  ---  --

以下のようにしてヘッダーを指定することもできます。

ヘッダーの指定

>>> print(tabulate(data, headers=['id', 'name', 'age']))
  id  name      age
----  ------  -----
   0  foo        25
   1  bar        32
   2  baz        59

行のリスト(dict)

dictのリストでも問題ありません。 この場合headers='keys'とすることでヘッダーを指定できます。

行のリスト

>>> data = [
...     {'id': 0, 'name': 'foo', 'age': 25},
...     {'id': 1, 'name': 'bar', 'age': 32},
...     {'id': 2, 'name': 'baz', 'age': 59},
... ]
>>> print(tabulate(data, headers='keys'))
  id  name      age
----  ------  -----
   0  foo        25
   1  bar        32
   2  baz        59

データのスキーマが一致しない場合でも適宜空白を入れてくれます。

データの欠落

>>> data = [
...     {         'name': 'foo', 'age': 25},
...     {'id': 1, 'name': 'bar'           },
...     {'id': 2,                'age': 59},
... ]
>>> print(tabulate(data, headers='keys'))
name      age    id
------  -----  ----
foo        25
bar               1
           59     2

列のdict

列をdictとして表したデータでも問題ありません。

列のdict

>>> data = {
...     'id': [0, 1, 2],
...     'name': ['foo', 'bar', 'baz'],
...     'age': [25, 32, 59]
... }
>>> print(tabulate(data, headers='keys'))
  id  name      age
----  ------  -----
   0  foo        25
   1  bar        32
   2  baz        59

行のリストと挙動は少し異なりますがデータの欠落にも対応してくれます。

データの欠落

>>> data = {
...     'id': [1, 2],
...     'name': ['foo', 'bar', 'baz'],
...     'age': [25, 32, 59]
... }
>>> print(tabulate(data, headers='keys'))
  id  name      age
----  ------  -----
   1  foo        25
   2  bar        32
      baz        59

出力のフォーマットを変える

フォーマットはtablefmtの値を変えることで変更できます。 デフォルトはsimpleです。 ここでは以下のように定義したデータとヘッダーを使います。

データの定義

>>> data = [
...     (0, 'foo', 25),
...     (1, 'bar', 32),
...     (2, 'baz', 59),
... ]
>>> headers = ['id', 'name', 'age']

ここで紹介するもの以外のフォーマットも沢山あります。

simple

simple

>>> print(tabulate(data, headers=headers, tablefmt='simple'))
  id  name      age
----  ------  -----
   0  foo        25
   1  bar        32
   2  baz        59

Markdown(GitHub)

GitHubなどで使われるMarkdownです。

github

>>> print(tabulate(data, headers=headers, tablefmt='github'))
|   id | name   |   age |
|------|--------|-------|
|    0 | foo    |    25 |
|    1 | bar    |    32 |
|    2 | baz    |    59 |

fancy_grid

fancy

>>> print(tabulate(data, headers=headers, tablefmt='fancy_grid'))
╒══════╤════════╤═══════╕
│   id │ name   │   age │
╞══════╪════════╪═══════╡
│    0 │ foo    │    25 │
├──────┼────────┼───────┤
│    1 │ bar    │    32 │
├──────┼────────┼───────┤
│    2 │ baz    │    59 │
╘══════╧════════╧═══════╛

HTML

html

>>> print(tabulate(data, headers=headers, tablefmt='html'))
<table>
<thead>
<tr><th style="text-align: right;">  id</th><th>name  </th><th style="text-align: right;">  age</th></tr>
</thead>
<tbody>
<tr><td style="text-align: right;">   0</td><td>foo   </td><td style="text-align: right;">   25</td></tr>
<tr><td style="text-align: right;">   1</td><td>bar   </td><td style="text-align: right;">   32</td></tr>
<tr><td style="text-align: right;">   2</td><td>baz   </td><td style="text-align: right;">   59</td></tr>
</tbody>
</table>

LaTex

latex

>>> print(tabulate(data, headers=headers, tablefmt='latex'))
\begin{tabular}{rlr}
\hline
   id & name   &   age \\
\hline
    0 & foo    &    25 \\
    1 & bar    &    32 \\
    2 & baz    &    59 \\
\hline
\end{tabular}

インデックスを表示する

showindexでインデックスを表示するかどうかを変更できます。

インデックスの表示

>>> print(tabulate(data, headers=headers, showindex=True))
      id  name      age
--  ----  ------  -----
 0     0  foo        25
 1     1  bar        32
 2     2  baz        59

リストなどでもインデックスを指定できます。

インデックスをリストで指定

print(tabulate(data, headers=headers, showindex=['a', 'b', 'c']))
      id  name      age
--  ----  ------  -----
a      0  foo        25
b      1  bar        32
c      2  baz        59

列を揃える

列を揃えることもできます。 データの型ごとに一括して指定することもできます。

列を揃える

>>> print(tabulate(data, headers=headers))
  id  name      age
----  ------  -----
   0  foo        25
   1  bar        32
   2  baz        59
>>> print(tabulate(data, headers=headers, stralign='center', numalign='left'))
id     name   age
----  ------  -----
0      foo    25
1      bar    32
2      baz    59

colalignを使用すれば列ごとに揃え方を指定することもできます。

揃え方を列ごとに指定

>>> print(tabulate(data, headers=headers, colalign=('left', 'center','right')))
id     name     age
----  ------  -----
0      foo       25
1      bar       32
2      baz       59

Float型のフォーマット

floatfmtを使用すればFloat型をどのように表示するかを指定することも可能です。

不動小数点のフォーマット

>>> print(tabulate([['pi', 3.141592]], floatfmt='.4f'))
--  ------
pi  3.1416
--  ------

感想

様々な形式の表を生成できるのは便利です。 CLI、ブログ、レポート、論文など使用できる局面は多いと思います。 値の表示方法も指定できるので綺麗な表が作れる気がします。