Pythonライブラリ `tabulate` 詳細解説:ターミナルやレポートで見やすい表を作成しよう!

Pythonを使ってデータを扱う際、リストや辞書、あるいはPandas DataFrameなどの形式でデータを持つことは多いでしょう。これらのデータをそのまま表示すると、特にデータ量が多い場合やターミナルでの確認時には、非常に見づらくなってしまうことがあります。そんなときに活躍するのが、Pythonライブラリの tabulate です。

tabulate は、様々な形式の表形式データを、人間に読みやすいプレーンテキストの表(テーブル)や、HTML、Markdown、LaTeXなどの形式で簡単に出力できる非常に便利なライブラリです。コマンドラインインターフェース(CLI)でのデータ表示、Jupyter Notebookでの結果表示、簡単なレポート作成など、多岐にわたる場面で役立ちます。今回は、この tabulate の基本的な使い方から、応用的な機能までを詳しく解説していきます。

インストール

tabulate ライブラリは、Pythonの標準ライブラリではないため、別途インストールが必要です。pipコマンドを使って簡単にインストールできます。ターミナル(またはコマンドプロンプト)で以下のコマンドを実行してください。

pip install tabulate

特定のユーザーのみにインストールしたい場合は --user オプションを追加します。

pip install tabulate --user

また、日本語のような全角文字(ワイドキャラクター)を含む表を正しく扱うためには、wcwidth ライブラリが追加で必要になる場合があります。以下のコマンドで tabulate と一緒にインストールできます。

pip install tabulate[widechars]

wcwidth がインストールされていれば、全角文字のサポートは自動的に有効になります。

基本的な使い方

tabulate の基本的な使い方は非常にシンプルです。メインとなる tabulate() 関数に、表にしたいデータと、必要に応じてヘッダー情報を渡すだけです。

リストのリスト (List of Lists)

最も基本的なデータ形式は、リストのリスト(あるいはタプルのリストなど、イテラブルのイテラブル)です。

from tabulate import tabulate

# サンプルデータ(リストのリスト)
data = [
    ["太陽", 696000, 1989100000],
    ["地球", 6371, 5973.6],
    ["月", 1737, 73.5],
    ["火星", 3390, 641.85]
]

# ヘッダー情報
headers = ["天体名", "半径 (km)", "質量 (x 10^21 kg)"]

# 表形式で出力
print(tabulate(data, headers=headers))

これを実行すると、以下のような整形された表が標準出力に表示されます。

天体名      半径 (km)    質量 (x 10^21 kg)
--------  -----------  -------------------
太陽           696000          1.9891e+09
地球             6371          5973.6
月               1737            73.5
火星             3390           641.85

headers 引数を指定しない場合は、ヘッダーなしの表が出力されます。また、headers="firstrow" と指定すると、データの最初の行がヘッダーとして使用されます。

data_with_header = [
    ["天体名", "半径 (km)", "質量 (x 10^21 kg)"],
    ["太陽", 696000, 1989100000],
    ["地球", 6371, 5973.6],
    ["月", 1737, 73.5],
    ["火星", 3390, 641.85]
]

print(tabulate(data_with_header, headers="firstrow"))

出力結果:

天体名      半径 (km)    質量 (x 10^21 kg)
--------  -----------  -------------------
太陽           696000          1.9891e+09
地球             6371          5973.6
月               1737            73.5
火星             3390           641.85

辞書のリスト (List of Dictionaries)

辞書のリスト形式のデータも扱うことができます。この場合、デフォルトでは辞書のキーがヘッダーとして使用されます。

from tabulate import tabulate

data_dict_list = [
    {'天体名': '太陽', '半径 (km)': 696000, '質量 (x 10^21 kg)': 1989100000},
    {'天体名': '地球', '半径 (km)': 6371, '質量 (x 10^21 kg)': 5973.6},
    {'天体名': '月', '半径 (km)': 1737, '質量 (x 10^21 kg)': 73.5},
    {'天体名': '火星', '半径 (km)': 3390, '質量 (x 10^21 kg)': 641.85}
]

# headers="keys" はデフォルトなので省略可能
print(tabulate(data_dict_list, headers="keys"))

出力結果:

天体名      半径 (km)    質量 (x 10^21 kg)
--------  -----------  -------------------
太陽           696000          1.9891e+09
地球             6371          5973.6
月               1737            73.5
火星             3390           641.85

その他のデータ形式

tabulate は、他にも以下のデータ形式をサポートしています。

  • 辞書のイテラブル(キーがカラム名)
  • 2次元 NumPy 配列
  • NumPy レコード配列(フィールド名がカラム名)
  • pandas DataFrame
  • リストやイテラブルの dataclass (Python 3.7+)

特に pandas DataFrame との連携は強力です。

import pandas as pd
from tabulate import tabulate

# pandas DataFrame の作成
df = pd.DataFrame(data_dict_list)

# DataFrame を tabulate で表示 (インデックスは表示しない)
print(tabulate(df, headers='keys', tablefmt='psql', showindex=False))

出力結果 (psql フォーマット):

+----------+-------------+-----------------------+
| 天体名   |   半径 (km) |   質量 (x 10^21 kg) |
|----------+-------------+-----------------------|
| 太陽     |      696000 |            1.9891e+09 |
| 地球     |        6371 |         5973.6        |
| 月       |        1737 |           73.5        |
| 火星     |        3390 |          641.85       |
+----------+-------------+-----------------------+

showindex=False で DataFrame のインデックスを非表示にしています。代わりに showindex="always" とすると、常にインデックスが表示されます。

テーブルフォーマット (tablefmt)

tabulate の大きな特徴の一つが、豊富な出力フォーマットをサポートしている点です。tabulate() 関数の tablefmt 引数で、出力する表のスタイルを指定できます。

以下にいくつかの代表的なフォーマットと、その出力例を示します。(データは前述のリストのリストを使用)

plain (デフォルトに近いシンプルな形式)

print(tabulate(data, headers=headers, tablefmt="plain"))
天体名    半径 (km)    質量 (x 10^21 kg)
太陽         696000          1.9891e+09
地球           6371          5973.6
月             1737            73.5
火星           3390           641.85

simple (Pandoc simple_tables 形式)

print(tabulate(data, headers=headers, tablefmt="simple"))
天体名      半径 (km)    質量 (x 10^21 kg)
--------  -----------  -------------------
太陽           696000          1.9891e+09
地球             6371          5973.6
月               1737            73.5
火星             3390           641.85

github (GitHub Flavored Markdown 形式)

print(tabulate(data, headers=headers, tablefmt="github"))
| 天体名   |   半径 (km) |   質量 (x 10^21 kg) |
|----------|-------------|---------------------|
| 太陽     |      696000 |          1.9891e+09 |
| 地球     |        6371 |          5973.6     |
| 月       |        1737 |            73.5     |
| 火星     |        3390 |           641.85    |

この形式は、GitHubのMarkdownファイルやQiitaなどのサービスで表を記述する際に便利です。

grid (罫線で囲まれた形式)

print(tabulate(data, headers=headers, tablefmt="grid"))
+----------+-------------+-----------------------+
| 天体名   |   半径 (km) |   質量 (x 10^21 kg) |
+==========+=============+=======================+
| 太陽     |      696000 |            1.9891e+09 |
+----------+-------------+-----------------------+
| 地球     |        6371 |            5973.6     |
+----------+-------------+-----------------------+
| 月       |        1737 |              73.5     |
+----------+-------------+-----------------------+
| 火星     |        3390 |             641.85    |
+----------+-------------+-----------------------+

fancy_grid (grid より少し装飾的な罫線)

print(tabulate(data, headers=headers, tablefmt="fancy_grid"))
╒══════════╤═════════════╤═══════════════════════╕
│ 天体名   │   半径 (km) │   質量 (x 10^21 kg) │
╞══════════╪═════════════╪═══════════════════════╡
│ 太陽     │      696000 │            1.9891e+09 │
├──────────┼─────────────┼───────────────────────┤
│ 地球     │        6371 │            5973.6     │
├──────────┼─────────────┼───────────────────────┤
│ 月       │        1737 │              73.5     │
├──────────┼─────────────┼───────────────────────┤
│ 火星     │        3390 │             641.85    │
╘══════════╧═════════════╧═══════════════════════╛

pipe (PHP Markdown Extra 形式)

print(tabulate(data, headers=headers, tablefmt="pipe"))
| 天体名   |   半径 (km) |   質量 (x 10^21 kg) |
|:---------|------------:|--------------------:|
| 太陽     |      696000 |          1.9891e+09 |
| 地球     |        6371 |          5973.6     |
| 月       |        1737 |            73.5     |
| 火星     |        3390 |           641.85    |

html (HTML 形式)

print(tabulate(data, headers=headers, tablefmt="html"))

出力されるHTMLは以下のようになります(整形済み)。このブログのようにBulmaなどのCSSフレームワークと組み合わせると、簡単に見栄えの良い表をWebページに埋め込めます。

天体名 半径 (km) 質量 (x 10^21 kg)
太陽 696000 1.9891e+09
地球 6371 5973.6
1737 73.5
火星 3390 641.85

これら以外にも、latex, latex_raw, latex_booktabs, rst, mediawiki, jira, tsv など、多数のフォーマットがサポートされています。レポート作成、ドキュメント生成、Wikiへの貼り付けなど、用途に応じて最適なフォーマットを選択できます。

利用可能なフォーマットの一覧は、tabulate.tabulate_formats で確認できます。

from tabulate import tabulate_formats

print(tabulate_formats)

アライメント(配置)の調整

tabulate は賢く、列の内容に応じて自動的にアライメント(テキストの配置)を調整してくれます。デフォルトでは、数値データ(整数や浮動小数点数)は右寄せ(小数点がある場合は小数点基準)、それ以外のテキストデータは左寄せになります。

このデフォルトの挙動は、numalign(数値)と stralign(文字列)引数で変更できます。指定できる値は "right", "center", "left" です。数値の場合のみ "decimal" (小数点揃え)も指定可能です。None を指定するとアライメントが無効になります。

全体の数値・文字列アライメントを変更

from tabulate import tabulate

data = [
    ["Alice", 24, 1200.50],
    ["Bob", 30, 850.75],
    ["Charlie", 22, 2100.00]
]
headers = ["名前", "年齢", "給与"]

# 数値を左寄せ、文字列を中央寄せにする
print(tabulate(data, headers=headers, numalign="left", stralign="center", tablefmt="grid"))

出力結果:

+---------+--------+--------+
|  名前   | 年齢   | 給与   |
+=========+========+========+
|  Alice  | 24     | 1200.5 |
+---------+--------+--------+
|   Bob   | 30     | 850.75 |
+---------+--------+--------+
| Charlie | 22     | 2100.0 |
+---------+--------+--------+

列ごとにアライメントを指定 (colalign)

さらに細かく、列ごとにアライメントを指定したい場合は colalign 引数を使用します。この引数には、各列のアライメント設定をタプルまたはリストで渡します。

from tabulate import tabulate

data = [
    ["Alice", 24, 1200.50],
    ["Bob", 30, 850.75],
    ["Charlie", 22, 2100.00]
]
headers = ["名前", "年齢", "給与"]

# 1列目: 左寄せ, 2列目: 中央寄せ, 3列目: 右寄せ
print(tabulate(data, headers=headers, colalign=("left", "center", "right"), tablefmt="grid"))

出力結果:

+---------+--------+--------+
| 名前    |  年齢  |   給与 |
+=========+========+========+
| Alice   |   24   | 1200.5 |
+---------+--------+--------+
| Bob     |   30   | 850.75 |
+---------+--------+--------+
| Charlie |   22   | 2100.0 |
+---------+--------+--------+

このように、colalign を使うことで、データの種類や見せたい意図に合わせて、より柔軟なアライメント調整が可能です。

注意点として、tabulate は数値を自動で認識しようとしますが、この処理を無効にしたい場合は disable_numparse=True を指定します。

数値フォーマット (floatfmt, intfmt)

小数点を含む数値(浮動小数点数)や整数の表示形式もカスタマイズできます。

浮動小数点数のフォーマット (floatfmt)

floatfmt 引数を使うと、浮動小数点数の表示形式を Python の標準的なフォーマット指定文字列(例: ".2f" で小数点以下2桁表示)や、より高度な指定方法で制御できます。

from tabulate import tabulate

data = [
    ["Item A", 12.3456, 0.987],
    ["Item B", 1234.5, 0.1],
    ["Item C", 1.2, 0.005]
]
headers = ["商品名", "価格", "割引率"]

# 価格は小数点以下2桁、割引率はパーセント表示 (小数点以下1桁)
print(tabulate(data, headers=headers, floatfmt=(".2f", ".1%"), tablefmt="pipe"))

出力結果:

| 商品名   |   価格 |   割引率 |
|:---------|-------:|---------:|
| Item A   |  12.35 |    98.7% |
| Item B   | 1234.50 |    10.0% |
| Item C   |   1.20 |     0.5% |

floatfmt にタプルやリストを渡すことで、列ごとに異なるフォーマットを指定できます。

整数のフォーマット (intfmt)

同様に intfmt 引数で整数の表示形式を指定できます。例えば、桁区切りカンマを入れるなどが可能です。

from tabulate import tabulate

data = [
    ["Population", 123456789, 9876543],
    ["Area (sq km)", 377975, 10000]
]
headers = ["項目", "日本", "東京"]

# 整数にカンマ区切りを入れる
print(tabulate(data, headers=headers, intfmt=",", tablefmt="grid"))

出力結果:

+----------------+-------------+----------+
| 項目           | 日本        | 東京     |
+================+=============+==========+
| Population     | 123,456,789 | 9,876,543|
+----------------+-------------+----------+
| Area (sq km)   | 377,975     | 10,000   |
+----------------+-------------+----------+

欠損値の表示 (missingval)

データ中に None が含まれる場合、デフォルトでは空欄として表示されますが、missingval 引数で表示する文字列を指定できます。

from tabulate import tabulate

data = [
    ["Alice", 24, 1200.50],
    ["Bob", None, 850.75], # 年齢が欠損
    ["Charlie", 22, None]  # 給与が欠損
]
headers = ["名前", "年齢", "給与"]

print(tabulate(data, headers=headers, missingval="N/A", tablefmt="simple"))

出力結果:

名前       年齢      給与
---------  ------  ------
Alice        24    1200.5
Bob         N/A     850.75
Charlie      22    N/A

長いテキストの折り返し (maxcolwidths)

テーブルのセルに含まれるテキストが非常に長い場合、表全体の幅が広がりすぎて見にくくなることがあります。tabulate では maxcolwidths 引数を使って、列の最大幅を指定し、それを超えるテキストを自動的に折り返す(改行する)機能があります。

maxcolwidths には、各列の最大幅を整数で指定したリストまたはタプルを渡します。すべての列に同じ最大幅を適用したい場合は、単一の整数を渡すこともできます。特定の列に最大幅を設定したくない場合は、リスト/タプル内でその列に対応する要素を None にします。

テキストの折り返し処理には、Python の標準ライブラリ textwrap が内部で使用されます。

from tabulate import tabulate

data = [
    [1, "非常に長い説明文が入ります。このテキストは指定された幅を超えると自動的に折り返されます。", 100],
    [2, "短い説明文", 200],
    [3, "こちらもかなり長い説明文です。改行されて見やすくなるはずです。", 150]
]
headers = ["ID", "説明", "値"]

# 2列目の最大幅を30文字に設定
print(tabulate(data, headers=headers, maxcolwidths=[None, 30, None], tablefmt="grid"))

出力結果:

+------+--------------------------------+-------+
|   ID | 説明                           |   値 |
+======+================================+=======+
|    1 | 非常に長い説明文が入ります。   |   100 |
|      | このテキストは指定された幅を超 |       |
|      |えると自動的に折り返されます。  |       |
+------+--------------------------------+-------+
|    2 | 短い説明文                     |   200 |
+------+--------------------------------+-------+
|    3 | こちらもかなり長い説明文です。 |   150 |
|      | 改行されて見やすくなるはずです。|       |
+------+--------------------------------+-------+

このように、maxcolwidths を使うことで、長いテキストを含む表でも、レイアウト崩れを防ぎ、読みやすさを保つことができます。

活用例

tabulate は様々な場面で役立ちます。

  • コマンドラインツール(CLI)での出力: スクリプトの実行結果を整形して表示する際に非常に便利です。
  • Jupyter Notebook/Lab: データ分析の過程や結果をノートブック上で分かりやすく表示できます。特にHTMLフォーマットはインタラクティブな環境と相性が良いです。
  • 簡単なレポート生成: Markdown や LaTeX フォーマットで出力すれば、そのままレポートやドキュメントに組み込めます。
  • デバッグ時のデータ確認: 複雑なデータ構造の中身を一時的に確認したい場合にも、手軽に整形された表形式で表示できるため役立ちます。
  • Webアプリケーション: HTMLフォーマットで出力し、Webフレームワーク (Flask, Djangoなど) のテンプレートに埋め込むことで、動的にテーブルを生成できます。

例えば、2025年1月に公開されたZennの記事では、複数のExcelファイルを読み込み、その内容を tabulate を使ってMarkdown形式に変換し、一つのファイルにまとめることで、生成AIでの解析を容易にするという活用例が紹介されていました。これにより、大量の表データをAIに効率的に入力し、要約や洞察を得ることが可能になります。

まとめ

tabulate は、Pythonで表形式データを扱う際に、驚くほど簡単に、そして柔軟に見栄えの良いテーブルを作成できる強力なライブラリです。たった1つの関数 tabulate() を覚えるだけで、様々なデータソースと出力フォーマットに対応でき、アライメントや数値フォーマットの調整も可能です。

日々の開発作業やデータ分析において、結果を見やすく表示したい、あるいは簡単なレポートを作成したいといったニーズは頻繁に発生します。tabulate を活用することで、これらの作業を効率化し、より質の高いアウトプットを生み出す手助けとなるでしょう。ぜひ、あなたのPythonプロジェクトに取り入れてみてください!