- はじめに -
データ分析、機械学習という仕事柄、csvやtsvを見る機会が多い。
処理する時は大体はpythonのpandasで読み込んで〜とするのだが、コンソール上で作業する時、どうしても「このcsvなんだっけ…」という事が発生する。
cat hoge.csv | head
等として上部だけ見たり、jsonならjqコマンドに流すのだが、いかんせん見栄えの問題で一瞬で判断出来なかったりする。
https://stedolan.github.io/jq/
そこで、table形式にしてコンソール上で表示して見れると嬉しいなと思って調べた事をまとめる記事。
端的に結果を最初に言うと、一般的なコンソールで使うだけならtty-tableコマンドとしてjqコマンドのように扱えるtty-table、CLIツールを今から作るならGoでtablewriter、python上でも資産として利用するならpython-tabulateが便利そうという事が分かった。
追記:
ん〜!わかる!
- CLIにtable表示するパッケージのまとめ -
CLIツールとして有名どころではNode.js製のcli-tableがある。
また、cli-tableのAPIと互換性を持ちつつリメイクされたcli-table2や、BoxやProgressBar等の実装も含まれるpixl-cliを使う選択肢がある。
Goだとtablewriter、Pythonだとpython-tabulateが良い。
Node.js実装
cli-table
Node.jsで書かれたCLI向けのテーブルビジュアライザ。
npmが入ってればすぐインストールできる。
npm install cli-table
簡単に扱えて
var Table = require('cli-table'); var table = new Table({head: ['X (train)', 'Y (label)'], colWidths: [20, 20]}); table.push(['hogehoge', 'piyo1'], ['fugafuga', 'piyo2']); console.log(table.toString());
中身でcolor.jsで色付けしてくれるので見やすい。
Horizontalにするにはlist、Verticalならdictを入れるだけ。
かなり簡易。
cli-table2
cli-tableの機能拡張リメイク
cli-tableのAPIを踏襲している上、セルごとに文字、色、paddingを設定できたり、行列にまたがるセルを生成できるのが強み。
npmで入れる
npm install cli-table2
基本的にはcli-tableと同じ感じで扱える。
var Table = require('cli-table2'); var table = new Table({head:['X', 'Y'], colWidths: [20, 20]}); table.push( [{colSpan:2,content:'None'}], ['hogehoge','piyo1'], ['fuga', 'piyo2'], ['fugefuga2',{rowSpan:2,content:'piyo4\npiyo5'}], ['fugafuga3'] ); console.log(table.toString());
なんか趣向と外れてきてる気がするが面白い。
以下のAdvanced-usageに面白そうな例が沢山あるので参考に。
cli-table2/advanced-usage.md at master · jamestalmage/cli-table2 · GitHub
pixl-cli
上記2つとは少し違って、コマンドラインでNode.jsを作る時のユーティリティが詰まったやつ。
ユーザinputやgraphical info boxes(boxだけでなくtableも扱える)、ProgressBar等が含まれている。
boxもしくはtableを使うと良さげに表示できる
var cli = require('pixl-cli'); cli.print( cli.box("This is Example!! :D") + '\n');
良さそう。
var cli = require('pixl-cli'); var rows = [ ['X (data)', 'Y (label)'], ['hoge', 'piyo1'], ['fuga', 'piyo2']]; cli.print(cli.table(rows)+'\n');
tableも複雑な事はできないが、list投げるだけなので所感は変わらず。
今回は割愛したがProgressBarも便利感あるし、Node.jsでCLIツール作る時はこれ使うと良さそう。
Ruby実装
terminal-table
ASCIIでtableをよしなに表示するやつ。
Rubyなのでgemでインストールする
gem install terminal-table
サンプルを適当に動かす。
require 'terminal-table' rows = [['hoge', 1], ['piyo', 2], ['fuga', 'test']] table = Terminal::Table.new :title => "Header Sample", :headings => ['X', 'Y'], :rows => rows puts table
色も良いけど、やっぱりASCIIが可愛い。
よしなに文字幅等調整するようになってるので、tableのline変えても結構自由に動く。
でも個人的には、RubyでCLIツール作る機会がほぼ無くなってしまったので使う機会があれば。
tty-table
rubyのTTY toolkit用に作られているtableビジュアライザ。
他のパッケージと違って、インストール時点でコマンドとして使えるのが良さ。
言語関係なくCLIで使うだけなら一番楽だと思う。
また、どの形式でtableを形成するか選べて、unicodeやASCIIが選べる。
gemで入れる
gem install tty-table
TTY::TableやTTY::Table::Rendererが用意されているので、それぞれinitializeして表示。
require 'tty-table' rows = [['hoge', 1], ['piyo', 2], ['fuga', 'test']] table = TTY::Table.new rows renderer = TTY::Table::Renderer::ASCII.new(table) puts renderer.render
試しにASCIIで出したが良い感じ。
コマンドでも出せて、これが便利感がある。
例えば以下みたくcsvを表示してみる。
cat titanic.csv | head | tty-table
みんな大好きtitanicデータ。
コマンドだと--formatでjsonも指定できたり、--csv-delimiterで'\t'指定すればtsvをtable表示したりもできるので使い勝手がすごい。
Go実装
tablewriter
Goだとtablewriter一択だと勝手に思っている。
知らない間に以下も吸収されていた。
GitHub - crackcomm/go-clitable: Command line (ASCII) and Markdown table for Golang. You probably want to take a look at: https://github.com/olekukonko/tablewriter
機能面では一番使い勝手が良い。
CSVや他Separatorが扱えるだけでなく、行列内のセル、Markdown Formatまで実装されている。
Captionをつける機能もあって、多分CLIでtable作る時は一番便利に扱える。
go get github.com/olekukonko/tablewriter
以下見たくgoファイル作ってツール化。
package main import "os" import "github.com/olekukonko/tablewriter" func main() { data := [][]string{ []string{"hoge", "String", "SAMPLE"}, []string{"piyo", "Int", "10"}, []string{"fuga", "Int", "10"}, } table := tablewriter.NewWriter(os.Stdout) table.SetHeader([]string{"X", "TYPE", "VALUE"}) for _, v := range data { table.Append(v) } table.Render() }
inputにCSVも使える上、Docも充実。
tablewriter - GoDoc
自前でtable見るツール作るならベストだし、割りとGoでCLIツール作られている事が多くなってきたので絶対使いそう。
Python実装
python-prettytable
redhatのdprince氏が作っているprettytable。
READMEに気合いが入っていている。
pythonなのでpipで導入する。
pip install prettytable
READMEにはset_field_namesなるmethodがあると書いてあったが見当たらず以下のように
from prettytable import PrettyTable x = PrettyTable() x.field_names = ['X', 'Y', 'VALUE'] x.add_row(['hoge', 'piyo1', '1']) x.add_row(['fuga', 'piyo2', '2']) print(x.get_string())
prettytableの良いところとして、get_html_stringなるmethodがあり、html形式のtable取得ができるので、Webアプリ等に直接返す時にちょっと使えそう。
python-tabulate
多分多くのPythonパッケージではこれが利用されてると思う。
pipで導入していく
pip install tabulate
普通にリスト投げるだけで良いので扱いやすい点でユーザが多いのだと思う。
from tabulate import tabulate table = [["hoge",1],["piyo",2],["fuga",3]] headers = ["X (data)", "Y (label)"] print(tabulate(table, headers, tablefmt="grid"))
outputの形式が充実していて、一般的なtableのgrid形式から、PHP MarkdownのpipeやEmacs org-mode、wiki、LaTeX markup形式としても出せる。
また、入力としてpandasも対応している。
つよい。
でどれが良さそうなのよ
最初にも書いた通り、「すぐコマンドとして使いたい」ならtty-tableが良い。
cat csvしてtty-tableコマンドに流すだけ。
CLIツールを今から作るならtablewriterでコマンド作って流す形にするのが良さそう。
機能が一番充実しているし、Docも充実している。
Goは良いぞ。
python上でも資産として利用するならpython-tabulateが便利そう。
本当の事を言うと、コンソール上で使いたいというよりxonsh上で使いたいという気持ちが強いので、個人的にはこれを使っていく事になると思う。
python-tabulateにhtml形式のoutput実装してmergeしてもらえば今の所満足そう。
rubyのとnodeは使って見た上で保留。
pixl-cliはめっちゃ使えそうだけどCLIツール最近はGoで書いてて、Node.jsはもっぱらGCP周りで使うくらいなのでう〜ん…
他言語も保留。