静かなる名辞

pythonとプログラミングのこと


【python】pandasのDataFrameをLaTeX出力

 そんな機能があるらしい。DataFrame.to_latex()という名前のメソッドである。

pandas.DataFrame.to_latex — pandas 0.21.1 documentation

 これが使えると何かの役に立つかもしれないので、使い物になるかどうか確認してみる。

お試し

 とりあえず、てきとーにdfを作ってみる。中身に意味はないけど、意味のないdfをできるだけ手っ取り早く作りたかったのでnumpy配列から作っている。*1

>>> import numpy as np
>>> import pandas as pd
>>> df = pd.DataFrame(np.arange(32).reshape(8,4), columns=list("abcd"))
>>> df
    a   b   c   d
0   0   1   2   3
1   4   5   6   7
2   8   9  10  11
3  12  13  14  15
4  16  17  18  19
5  20  21  22  23
6  24  25  26  27
7  28  29  30  31

 そのまま何も考えず、to_latex()を呼ぶ。strで返っても都合が悪いのでprintしてみる。

>>> print(df.to_latex())
\begin{tabular}{lrrrr}
\toprule
{} &   a &   b &   c &   d \\
\midrule
0 &   0 &   1 &   2 &   3 \\
1 &   4 &   5 &   6 &   7 \\
2 &   8 &   9 &  10 &  11 \\
3 &  12 &  13 &  14 &  15 \\
4 &  16 &  17 &  18 &  19 \\
5 &  20 &  21 &  22 &  23 \\
6 &  24 &  25 &  26 &  27 \\
7 &  28 &  29 &  30 &  31 \\
\bottomrule
\end{tabular}

 そしたらこれを別途作ったTeXのソースに貼る。ドキュメント曰く、

Render an object to a tabular environment table. You can splice this into a LaTeX document. Requires \usepackage{booktabs}.

 (強調は僕が勝手に付けたもの)

 ということらしい。とにかく次のようなTeXファイルを作ってみた。

\documentclass{jsarticle}
\usepackage{booktabs}

\begin{document}

\begin{table}[h]
\begin{tabular}{lrrrr}
\toprule
{} &   a &   b &   c &   d \\
\midrule
0 &   0 &   1 &   2 &   3 \\
1 &   4 &   5 &   6 &   7 \\
2 &   8 &   9 &  10 &  11 \\
3 &  12 &  13 &  14 &  15 \\
4 &  16 &  17 &  18 &  19 \\
5 &  20 &  21 &  22 &  23 \\
6 &  24 &  25 &  26 &  27 \\
7 &  28 &  29 &  30 &  31 \\
\bottomrule
\end{tabular}
\end{table}

\end{document}

 TeXとかよくわからないけど、これでコンパイルできてこんな結果が得られた。

できた表

 なるほど、できてますね。

 フォーマットは、論文でよく見かける罫線の少ない表です。カッコいい気もするし、罫線多めのちょいダサな表の方が安心感があって良いような気もするという、人によって好みの分かれる奴です。

カスタマイズしてみよう

 たかがto_latex()なのに、なんかいろいろ引数があります。公式をまとめておきます。

  • bold_rows : boolean, default False

 インデックス列の文字がboldになる

  • column_format : str, default None

 \begin{tabular}{}の{}の中に入る列の書式を文字列で渡す

  • longtable : boolean, default will be read from the pandas config module Default: False

 TeXのlongtableだって。参考(外部サイト):[LaTeX]長い表を表示する - Qiita

  • escape : boolean, default will be read from the pandas config module Default: True.

 エスケープがうまく効くかどうかにかかってくるんだと思う

  • encoding : str, default None

 何も指定しないとpython2はascii, python3はutf-8になるらしい。

  • decimal : string, default ‘.’

 Character recognized as decimal separator, e.g. ‘,’ in Europe.
 (説明を読んでもよくわからん)

  • multicolumn : boolean, default True

Use multicolumn to enhance MultiIndex columns. The default will be read from the config module.

  • multicolumn_format : str, default ‘l’

The alignment for multicolumns, similar to column_format The default will be read from the config module.

  • multirow : boolean, default False

Use multirow to enhance MultiIndex rows. Requires adding a \usepackage{multirow} to your LaTeX preamble. Will print centered labels (instead of top-aligned) across the contained rows, separating groups via clines. The default will be read from the pandas config module.

 上の3つは使い方がよくわからない。まあ、たぶん使えば使えるんだろう。

 せっかくなので、インデックス列bold、罫線多めな表を作ってみようと思う。見た目がダサくなるはずだ。

>>> print(df.to_latex(bold_rows=True, column_format="|l|l|l|l|"))
\begin{tabular}{|l|l|l|l|}
\toprule
{} &   a &   b &   c &   d \\
\midrule
\textbf{0} &   0 &   1 &   2 &   3 \\
\textbf{1} &   4 &   5 &   6 &   7 \\
\textbf{2} &   8 &   9 &  10 &  11 \\
\textbf{3} &  12 &  13 &  14 &  15 \\
\textbf{4} &  16 &  17 &  18 &  19 \\
\textbf{5} &  20 &  21 &  22 &  23 \\
\textbf{6} &  24 &  25 &  26 &  27 \\
\textbf{7} &  28 &  29 &  30 &  31 \\
\bottomrule
\end{tabular}
\documentclass{jsarticle}
\usepackage{booktabs}

\begin{document}

\begin{table}[h]
\begin{tabular}{|l|l|l|l|l|}
\toprule
{} &   a &   b &   c &   d \\
\midrule
\textbf{0} &   0 &   1 &   2 &   3 \\
\textbf{1} &   4 &   5 &   6 &   7 \\
\textbf{2} &   8 &   9 &  10 &  11 \\
\textbf{3} &  12 &  13 &  14 &  15 \\
\textbf{4} &  16 &  17 &  18 &  19 \\
\textbf{5} &  20 &  21 &  22 &  23 \\
\textbf{6} &  24 &  25 &  26 &  27 \\
\textbf{7} &  28 &  29 &  30 &  31 \\
\bottomrule
\end{tabular}
\end{table}

\end{document}

 結果は、

f:id:hayataka2049:20180531015049p:plain

 なんか思ってたのと違う・・・\*rule系と縦罫線の相性が悪いので、\hlineに変えてみる(TeXソースを直接いじって)。

\documentclass{jsarticle}
\usepackage{booktabs}

\begin{document}

\begin{table}[h]
\begin{tabular}{|l|l|l|l|l|}
\hline
{} &   a &   b &   c &   d \\
\hline
\textbf{0} &   0 &   1 &   2 &   3 \\
\textbf{1} &   4 &   5 &   6 &   7 \\
\textbf{2} &   8 &   9 &  10 &  11 \\
\textbf{3} &  12 &  13 &  14 &  15 \\
\textbf{4} &  16 &  17 &  18 &  19 \\
\textbf{5} &  20 &  21 &  22 &  23 \\
\textbf{6} &  24 &  25 &  26 &  27 \\
\textbf{7} &  28 &  29 &  30 &  31 \\
\hline
\end{tabular}
\end{table}

\end{document}

f:id:hayataka2049:20180531015313p:plain

 これは期待通りの結果だが、わざわざpandasが出力されるものをいじってこうしたいか? と考えると、デフォルトで吐き出されたものをそのまま使った方が潔いかもしれない。

まとめ

 使えるか? というと、とても微妙な機能ですが、考えようによっては、データをDataFrameに入れさえすれば、TeXの表組みと格闘する必要が一切なくなります。
(デフォルトで出てきた表の見た目に満足できれば)

 なので、それなりにおすすめです。

*1:pandasの機能を試すときって、試すためのdf作るのがそもそも面倒くさいということが往々にしてある。みんなはどうやってるんだろうか