Parquetの中身を手軽に表示・確認するならコレを使おう！


皆さん、矩形データの保存にParquet使っていますか？
csvのようなテキストファイルと比較して、型の表現力が高く読み込みも速く、便利ですよね。

[私は一年前にApache Arrow共々存在を知って使い始めた](https://qiita.com/eitsupi/items/ce3e1b1fb0e45e0d45e3)のですけれど、この一年ですっかり「とりあえずParquetで」みたいな感じになりました。

ただ、テキストと異なって手軽に中身を確認できないのだけは悩みどころです。

## PythonやRで表示すると……

もちろんPythonやRを起動してParquetファイルを開いて中身を確認することもできるのですけれど、コマンドは長いです。試してみましょう。

まずはテスト用のParquetファイル`data.parquet`をRで用意しておきます。

```r:R
mtcars |> arrow::write_parquet("data.parquet")
```

このファイルをシェルからRのarrowパッケージを呼んで中身を見てみます。

```sh:Terminal
$ Rscript -e 'arrow::open_dataset("data.parquet") |> head() |> as.data.frame()'
   mpg cyl disp  hp drat    wt  qsec vs am gear carb
1 21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
2 21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
3 22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
4 21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
5 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
6 18.1   6  225 105 2.76 3.460 20.22  1  0    3    1
```

パイプラインで気持ちよく繋いでいけるものの、自動補完などのない状態で長くて書くのは大変です。

次にPythonのpolarsパッケージで表示してみましょう。

```sh:Terminal
$ python -c 'import polars as pl; df=pl.read_parquet("data.parquet"); print(df)'
shape: (32, 11)
┌──────┬─────┬───────┬───────┬─────┬─────┬─────┬──────┬──────┐
│ mpg  ┆ cyl ┆ disp  ┆ hp    ┆ ... ┆ vs  ┆ am  ┆ gear ┆ carb │
│ ---  ┆ --- ┆ ---   ┆ ---   ┆     ┆ --- ┆ --- ┆ ---  ┆ ---  │
│ f64  ┆ f64 ┆ f64   ┆ f64   ┆     ┆ f64 ┆ f64 ┆ f64  ┆ f64  │
╞══════╪═════╪═══════╪═══════╪═════╪═════╪═════╪══════╪══════╡
│ 21.0 ┆ 6.0 ┆ 160.0 ┆ 110.0 ┆ ... ┆ 0.0 ┆ 1.0 ┆ 4.0  ┆ 4.0  │
├╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌┤
│ 21.0 ┆ 6.0 ┆ 160.0 ┆ 110.0 ┆ ... ┆ 0.0 ┆ 1.0 ┆ 4.0  ┆ 4.0  │
├╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌┤
│ 22.8 ┆ 4.0 ┆ 108.0 ┆ 93.0  ┆ ... ┆ 1.0 ┆ 1.0 ┆ 4.0  ┆ 1.0  │
├╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌┤
│ 21.4 ┆ 6.0 ┆ 258.0 ┆ 110.0 ┆ ... ┆ 1.0 ┆ 0.0 ┆ 3.0  ┆ 1.0  │
├╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌┤
│ ...  ┆ ... ┆ ...   ┆ ...   ┆ ... ┆ ... ┆ ... ┆ ...  ┆ ...  │
├╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌┤
│ 15.8 ┆ 8.0 ┆ 351.0 ┆ 264.0 ┆ ... ┆ 0.0 ┆ 1.0 ┆ 5.0  ┆ 4.0  │
├╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌┤
│ 19.7 ┆ 6.0 ┆ 145.0 ┆ 175.0 ┆ ... ┆ 0.0 ┆ 1.0 ┆ 5.0  ┆ 6.0  │
├╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌┤
│ 15.0 ┆ 8.0 ┆ 301.0 ┆ 335.0 ┆ ... ┆ 0.0 ┆ 1.0 ┆ 5.0  ┆ 8.0  │
├╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌┤
│ 21.4 ┆ 4.0 ┆ 121.0 ┆ 109.0 ┆ ... ┆ 1.0 ┆ 1.0 ┆ 4.0  ┆ 2.0  │
└──────┴─────┴───────┴───────┴─────┴─────┴─────┴──────┴──────┘
```

表示は見やすくて良い感じですけれど、やはりコマンドが長く、書くのは大変です。

## どんどん使いやすくなってきたDuckDB CLI

ここからはもう少し手軽にParquetの中身を確認できるツールを紹介します。

まずは[DuckDB CLI](https://duckdb.org/docs/api/cli)、様々なところで組み込みDBとして使用されているDuckDBのシングルバイナリのCLIです。普通に起動した後でSQLを実行することも可能ですが、`-c`オプションからSQLを渡すこともできます。

注目すべきは最新バージョン（バージョン0.6）でFROM句から始まるSQLを許可するようになったことです。SELECT句を省いて、かなり短いコマンドでParquetの中身を表示させられます。

### 使用例

SQLクエリ中で、テーブル名としてParquetのファイル名を指定するだけで読み込んでくれます。

```sh:Terminal
$ duckdb -c "from data.parquet"
┌────────┬────────┬────────┬────────┬───┬────────┬────────┬────────┬────────┐
│  mpg   │  cyl   │  disp  │   hp   │ … │   vs   │   am   │  gear  │  carb  │
│ double │ double │ double │ double │   │ double │ double │ double │ double │
├────────┼────────┼────────┼────────┼───┼────────┼────────┼────────┼────────┤
│   21.0 │    6.0 │  160.0 │  110.0 │ … │    0.0 │    1.0 │    4.0 │    4.0 │
│   21.0 │    6.0 │  160.0 │  110.0 │ … │    0.0 │    1.0 │    4.0 │    4.0 │
│   22.8 │    4.0 │  108.0 │   93.0 │ … │    1.0 │    1.0 │    4.0 │    1.0 │
│   21.4 │    6.0 │  258.0 │  110.0 │ … │    1.0 │    0.0 │    3.0 │    1.0 │
│   18.7 │    8.0 │  360.0 │  175.0 │ … │    0.0 │    0.0 │    3.0 │    2.0 │
│   18.1 │    6.0 │  225.0 │  105.0 │ … │    1.0 │    0.0 │    3.0 │    1.0 │
│   14.3 │    8.0 │  360.0 │  245.0 │ … │    0.0 │    0.0 │    3.0 │    4.0 │
│   24.4 │    4.0 │  146.7 │   62.0 │ … │    1.0 │    0.0 │    4.0 │    2.0 │
│   22.8 │    4.0 │  140.8 │   95.0 │ … │    1.0 │    0.0 │    4.0 │    2.0 │
│   19.2 │    6.0 │  167.6 │  123.0 │ … │    1.0 │    0.0 │    4.0 │    4.0 │
│   17.8 │    6.0 │  167.6 │  123.0 │ … │    1.0 │    0.0 │    4.0 │    4.0 │
│   16.4 │    8.0 │  275.8 │  180.0 │ … │    0.0 │    0.0 │    3.0 │    3.0 │
│   17.3 │    8.0 │  275.8 │  180.0 │ … │    0.0 │    0.0 │    3.0 │    3.0 │
│   15.2 │    8.0 │  275.8 │  180.0 │ … │    0.0 │    0.0 │    3.0 │    3.0 │
│   10.4 │    8.0 │  472.0 │  205.0 │ … │    0.0 │    0.0 │    3.0 │    4.0 │
│   10.4 │    8.0 │  460.0 │  215.0 │ … │    0.0 │    0.0 │    3.0 │    4.0 │
│   14.7 │    8.0 │  440.0 │  230.0 │ … │    0.0 │    0.0 │    3.0 │    4.0 │
│   32.4 │    4.0 │   78.7 │   66.0 │ … │    1.0 │    1.0 │    4.0 │    1.0 │
│   30.4 │    4.0 │   75.7 │   52.0 │ … │    1.0 │    1.0 │    4.0 │    2.0 │
│   33.9 │    4.0 │   71.1 │   65.0 │ … │    1.0 │    1.0 │    4.0 │    1.0 │
│   21.5 │    4.0 │  120.1 │   97.0 │ … │    1.0 │    0.0 │    3.0 │    1.0 │
│   15.5 │    8.0 │  318.0 │  150.0 │ … │    0.0 │    0.0 │    3.0 │    2.0 │
│   15.2 │    8.0 │  304.0 │  150.0 │ … │    0.0 │    0.0 │    3.0 │    2.0 │
│   13.3 │    8.0 │  350.0 │  245.0 │ … │    0.0 │    0.0 │    3.0 │    4.0 │
│   19.2 │    8.0 │  400.0 │  175.0 │ … │    0.0 │    0.0 │    3.0 │    2.0 │
│   27.3 │    4.0 │   79.0 │   66.0 │ … │    1.0 │    1.0 │    4.0 │    1.0 │
│   26.0 │    4.0 │  120.3 │   91.0 │ … │    0.0 │    1.0 │    5.0 │    2.0 │
│   30.4 │    4.0 │   95.1 │  113.0 │ … │    1.0 │    1.0 │    5.0 │    2.0 │
│   15.8 │    8.0 │  351.0 │  264.0 │ … │    0.0 │    1.0 │    5.0 │    4.0 │
│   19.7 │    6.0 │  145.0 │  175.0 │ … │    0.0 │    1.0 │    5.0 │    6.0 │
│   15.0 │    8.0 │  301.0 │  335.0 │ … │    0.0 │    1.0 │    5.0 │    8.0 │
│   21.4 │    4.0 │  121.0 │  109.0 │ … │    1.0 │    1.0 │    4.0 │    2.0 │
├────────┴────────┴────────┴────────┴───┴────────┴────────┴────────┴────────┤
│ 32 rows                                              11 columns (8 shown) │
└───────────────────────────────────────────────────────────────────────────┘
```

上の方の行だけを表示したい場合、単にLIMIT句を後に付ければ大丈夫です。

```sh:Terminal
 $ duckdb -c "from data.parquet limit 5"
┌────────┬────────┬────────┬────────┬───┬────────┬────────┬────────┬────────┐
│  mpg   │  cyl   │  disp  │   hp   │ … │   vs   │   am   │  gear  │  carb  │
│ double │ double │ double │ double │   │ double │ double │ double │ double │
├────────┼────────┼────────┼────────┼───┼────────┼────────┼────────┼────────┤
│   21.0 │    6.0 │  160.0 │  110.0 │ … │    0.0 │    1.0 │    4.0 │    4.0 │
│   21.0 │    6.0 │  160.0 │  110.0 │ … │    0.0 │    1.0 │    4.0 │    4.0 │
│   22.8 │    4.0 │  108.0 │   93.0 │ … │    1.0 │    1.0 │    4.0 │    1.0 │
│   21.4 │    6.0 │  258.0 │  110.0 │ … │    1.0 │    0.0 │    3.0 │    1.0 │
│   18.7 │    8.0 │  360.0 │  175.0 │ … │    0.0 │    0.0 │    3.0 │    2.0 │
├────────┴────────┴────────┴────────┴───┴────────┴────────┴────────┴────────┤
│ 5 rows                                               11 columns (8 shown) │
└───────────────────────────────────────────────────────────────────────────┘
```

ちなみに、Parquetはご覧の通り簡単に開けるのですが、csvの場合は関数を呼ぶ必要があり少々面倒でした。

### 推しポイント

- シングルバイナリ。
- 多機能。
- 活発にアップデートされている。
- Parquetの場合かなりクエリを書きやすい。

## headのように使えるqv

次に紹介するのは[qv](https://github.com/timvw/qv)、「Quickly view your data」と説明されているデータを素早く確認するためのコマンドラインツールです。内部ではApache Arrowのサブプロジェクトである、Apache Arrow DataFusionを使用しているようです。

「Parquetファイルに対して`head`コマンド[^1]使いたい～」と思いいくつかツールを試したところ、qvの使い心地が理想的でした。

[^1]: WindowsのPowerShell上では`get-content data.csv | select-object -first 10`のような感じ……長い……。

なお、どうもWindowsのパスの対応が芳しくないようで、Windows上で対象ファイルを絶対パスで指定した場合動作しませんでした……。

### 使用例

ファイル名のみを引数に取って`head`コマンドのように使えます。

```sh:Terminal
$ qv data.parquet
+------+-----+-------+-----+------+-------+-------+----+----+------+------+
| mpg  | cyl | disp  | hp  | drat | wt    | qsec  | vs | am | gear | carb |
+------+-----+-------+-----+------+-------+-------+----+----+------+------+
| 21   | 6   | 160   | 110 | 3.9  | 2.62  | 16.46 | 0  | 1  | 4    | 4    |
| 21   | 6   | 160   | 110 | 3.9  | 2.875 | 17.02 | 0  | 1  | 4    | 4    |
| 22.8 | 4   | 108   | 93  | 3.85 | 2.32  | 18.61 | 1  | 1  | 4    | 1    |
| 21.4 | 6   | 258   | 110 | 3.08 | 3.215 | 19.44 | 1  | 0  | 3    | 1    |
| 18.7 | 8   | 360   | 175 | 3.15 | 3.44  | 17.02 | 0  | 0  | 3    | 2    |
| 18.1 | 6   | 225   | 105 | 2.76 | 3.46  | 20.22 | 1  | 0  | 3    | 1    |
| 14.3 | 8   | 360   | 245 | 3.21 | 3.57  | 15.84 | 0  | 0  | 3    | 4    |
| 24.4 | 4   | 146.7 | 62  | 3.69 | 3.19  | 20    | 1  | 0  | 4    | 2    |
| 22.8 | 4   | 140.8 | 95  | 3.92 | 3.15  | 22.9  | 1  | 0  | 4    | 2    |
| 19.2 | 6   | 167.6 | 123 | 3.92 | 3.44  | 18.3  | 1  | 0  | 4    | 4    |
+------+-----+-------+-----+------+-------+-------+----+----+------+------+
```

`-q`オプションでSQLクエリを渡すこともできます。その場合、テーブル名として`tbl`を指定します。

```sh:Terminal
$ qv -q 'select * from tbl limit 5' data.parquet
+------+-----+------+-----+------+-------+-------+----+----+------+------+
| mpg  | cyl | disp | hp  | drat | wt    | qsec  | vs | am | gear | carb |
+------+-----+------+-----+------+-------+-------+----+----+------+------+
| 21   | 6   | 160  | 110 | 3.9  | 2.62  | 16.46 | 0  | 1  | 4    | 4    |
| 21   | 6   | 160  | 110 | 3.9  | 2.875 | 17.02 | 0  | 1  | 4    | 4    |
| 22.8 | 4   | 108  | 93  | 3.85 | 2.32  | 18.61 | 1  | 1  | 4    | 1    |
| 21.4 | 6   | 258  | 110 | 3.08 | 3.215 | 19.44 | 1  | 0  | 3    | 1    |
| 18.7 | 8   | 360  | 175 | 3.15 | 3.44  | 17.02 | 0  | 0  | 3    | 2    |
+------+-----+------+-----+------+-------+-------+----+----+------+------+
```

SQLを書く場合、SELECT句が必須な分DuckDBよりもコマンドは長くなりますね。

### 推しポイント

- シングルバイナリ。
- `head`コマンドのように、ファイル名だけを指定した場合に10行だけ表示してくれて手軽。
- csvも手軽に良い感じに表示してくれる。

## Excelのように表示してくれるTad

最後に紹介するのは、デスクトップアプリの[Tad](https://www.tadviewer.com/)です。Excelのような感じにParquetファイルの中身を表示してくれます。内部にはDuckDBが組み込まれているそうです。

Windowsでは拡張子への関連付けもできるため、ParquetはTadに関連付けしておけばダブルクリックで中身を見られるようになります！

コマンドラインからファイルを指定して実行もできます。

### 使用例

```sh:Terminal
tad data.parquet
```

![tad.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675583/cb0da4d3-0a3d-63be-e2cc-021e50ac4153.png)

### 推しポイント

- GUIで良い感じにParquetの中身を表示してくれてソート等も操作もでき、インタラクティブに中身を確認できる。

## その他

[Nushell](https://www.nushell.sh/)には少し前のバージョンまでParquet等を読み込む機能があったので追加のインストールなしでParquetを扱えたのですけれども（内部はpolars）、最近のリリースで配布バイナリからこの機能は削除されてしまったようで、自分でオプション付きでビルドしないと使えなくなってしまったようです。