Parquet の data encoding のサポート状況(2025年2月時点)
DuckDB が「DuckDB の新しいバージョンでは Parquet の新しめの encoding で書き出せるようになるけど、それを読めない奴らのせいでデフォルト有効にできないっすわ💢」というお気持ち表明ブログを書いていました。ここで「encoding」というのは、文字コードとかの話ではなくて、データをより少ないバイト数で記述する方法のことです。例えば、RLE(連長圧縮)のようなものです。
私はこれを読むまで Parquet の encoding の種類についてよく知らなかったので、勉強もかねてよく使われるツールの実装状況を調べてまとめてみます。
追記:公式に「Implementation status」というページがありました。書かれていないものも多いですが、ある程度は役立ちそうです。
新しめの data encoding
まずは Parquet の仕様を読みましょう。
このページによれば、非推奨の GROUP_VAR_INT
[1] と BIT_PACKED
を除くと、以下の encoding が仕様として定義されています。
-
Plain (
PLAIN
) -
Dictionary Encoding (
PLAIN_DICTIONARY
、RLE_DICTIONARY
) -
Run Length Encoding (
RLE
) -
Delta Encoding (
DELTA_BINARY_PACKED
): RLE をより効率的にした感じのやつ。整数向け。 -
Delta-length Byte Array (
DELTA_LENGTH_BYTE_ARRAY
): バイナリデータを詰めてくっつけてオフセットと長さを別で持っておくやつ。文字列やバイナリデータ向け。 -
Delta Strings (
DELTA_BYTE_ARRAY
): バイナリデータ版の delta encoding みたいなやつ。 -
Byte Stream Split (
BYTE_STREAM_SPLIT
): 実数向け。これは他のと違ってサイズは変わらないけど、この encoding をかけておくことで圧縮が効きやすくなるらしい。
DuckDB のブログによれば、BYTE_STREAM_SPLIT
は2019年から、それ以外も2015年にはすでに存在していた機能です。ということで、定義としてはまあまあ前からあるみたいです。
we're excited to have implemented the DELTA_BINARY_PACKED, DELTA_LENGTH_BYTE_ARRAY (added in Parquet 2.2.0 in 2015), and BYTE_STREAM_SPLIT (added in Parquet 2.8.0 in 2019) encodings in our Parquet writer.
DuckDB
DuckDB は、write に関しては次のバージョン(v1.2)からですが、read は少し前から実装されていました。
RLE
、DELTA_BINARY_PACKED
、DELTA_BYTE_ARRAY
、DELTA_LENGTH_BYTE_ARRAY
については 2022年(v0.7.0)から、
BYTE_STREAM_SPLIT
についても 2023年(v0.9.1)からサポートされていました。
Apache Arrow
2020年からサポートしてるみたいです。さすがは Apache project なだけあって早い。
ただ、BYTE_STREAM_SPLIT
は Parquet v2.8 で入ったものですが、Apache Arrow はそれを読み書きできるけどサポートしてるバージョンは v2.6 まで、ということになってるみたいです。謎...(実質なにか問題があるわけではなさそうな気はします)
Apache Spark
Spark では、read は DELTA_BINARY_PACKED
、DELTA_BYTE_ARRAY
、DELTA_LENGTH_BYTE_ARRAY
は 2022年(v3.3.0 )からサポートされています。BYTE_STREAM_SPLIT
に関しては今もサポートしていないようです。
write に関してはいずれもサポートされていません。そもそもチケットすら見つからないので、Spark は対応遅めなのかもですね...
Python
※あまり詳しくないです
pyarrow
(Apache Arrow と同じはず)
Pandas
Pandas が Parquet を読むときは、pyarrow があればそっちを、なければ fastparquet を使うようになっているはずです。pyarrow はまあ Arrow なので問題なく読み書きできるとして、fastparquet はというと、どうやら実装されているのは DELTA_BINARY_PACKED
の read までのようです。
Polars
Polars は 2024年(v1.0)で BYTE_STREAM_SPLIT
まで対応できています。読み書きどっちもだと思います。
R
arrow
(Apache Arrow と同じはず)
nanoparquet
nanoparquet 自体が去年 CRAN リリースされたばかりのもの[2]ですが、v0.3 の時点で BYTE_STREAM_SPLIT
の read までは対応しています。write は、RLE_DICTIONARY
v0.4 で使えるようになりましたが、それ以上の計画があるのかは不明です。
Trino
BYTE_STREAM_SPLIT
は2024年(v444)でサポートされていました。他はリリースノートに記述をみつけられなかったので、けっこう前からサポートされているんだと思います。
Presto
BYTE_STREAM_SPLIT
でコードを検索しても何も出ないので、対応してなさそうです。
https://github.com/search?q=repo%3Aprestodb%2Fpresto BYTE_STREAM_SPLIT &type=code
Hive
Hive は、Parquet 公式の Java 実装を使っていて、割と新しめなので普通に読めそうです。
以下の pull request を見て「まだバージョン 1.x なの...?」と思ってたら、これは Parquet フォーマットのバージョンではなく Java 実装のバージョンでした。
Tableau
DELTA_LENGTH_BYTE_ARRAY エンコードと最近の BYTE_STREAM_SPLIT エンコードは、どのライブラリでも記述されていないため、サポートされていません。これらのエンコーディングを使用している Parquet ファイルを見つけた場合は、お知らせください。
(https://help.tableau.com/current/pro/desktop/ja-jp/examples_amazons3.htm)
とのことです...。
Discussion