9.

Feather / Arrow IPC | Apache Arrow メモリ直マッピング形式解説

編集
この記事の要点
  • Feather / Arrow IPC (.feather / .ipc / .arrow) は Apache Arrow プロジェクトのインメモリ表形式
  • Pandas ↔ R 連携の高速バイナリブリッジとして Wes McKinney が 2016 年に開発
  • Arrow のカラムナメモリレイアウトをディスクに直書き。読み込みは memory-mapped で爆速
  • Parquet との違い: Feather は圧縮優先度低(容量大、速度最優先)
  • 機械学習パイプラインの中間データ、Pandas / Polars / R / DuckDB で共通読み込み

要点

  • Feather および Arrow IPCApache Arrow プロジェクトが提供する、メモリ上の列指向レイアウトをそのままディスクに書き出すバイナリ形式。拡張子は .feather / .arrow / .ipc
  • 2016 年、Pandas の作者 Wes McKinney と R の Hadley Wickham が「Pandas と R 間で高速にデータをやりとりしたい」目的で開発したのが始まり。
  • Apache Arrow のメモリレイアウトを直マッピングするため、読み込み時にパースや変換がほぼ不要で、起動コストが極端に小さい。
  • 長期保管・分析用途は Parquet が優位、言語間・プロセス間の高速 I/O 用に Feather/Arrow IPC を使うのが現代の定石。

概要

Apache Arrow は「言語に依存しない列指向のインメモリ表現」を統一しようとする OSS プロジェクトで、2016 年に Apache 配下で発足した。Pandas(Python)、data.frame(R)、Spark、Dremio、Drill、DuckDB など、それぞれが内部にバラバラの列指向構造を持っていたのを、同じバイト並びに揃えることでゼロコピーの相互運用を可能にする狙いがある。

その Arrow のメモリ表現を、そのままディスクに書き出したものが Arrow IPC ファイル形式で、初期にはこれを Feather v1 として公開していた。2019 年に仕様を統合する形で Feather v2 = Arrow IPC File Format となり、現在は Feather と Arrow IPC は実質同じものを指す。拡張子は慣習的に .feather(Pandas/R 文化)、.arrow / .ipc(Arrow 公式)と使い分けられる程度。

位置づけとしては Parquet と似て非なるもので、Parquet が「ディスク上でできるだけ小さく、長期保管に適する」ように圧縮とエンコーディングを尽くすのに対し、Feather/Arrow IPC は「メモリ表現と同じバイト並びで、読み込みコストをゼロに近づける」設計になっている。結果として、ファイルサイズは Parquet より大きくなるが、読み込み速度は Parquet を上回ることが多い。

内部構造

Arrow IPC ファイルは Schema → RecordBatch (複数) → Footer という構造で、各 RecordBatch は Arrow のメモリ表現と完全一致するバイト列を持つ。スキーマと長さ情報は Flatbuffers でメタデータ化されており、Flatbuffers のゼロコピー特性により、ファイルを mmap してそのまま列配列として扱える。

  1. Schema: 列名・型・nullable 情報。Flatbuffers エンコード。
  2. RecordBatch: 行を一定数まとめた塊。列ごとに「Validity Bitmap(NULL ビット)」「Offsets(可変長型のオフセット配列)」「Values(実データ)」が並ぶ。
  3. Footer: 各 RecordBatch のオフセット、終端マーカ。

圧縮は LZ4 / ZSTD を選べるが、デフォルトは無圧縮である。Parquet のように Dictionary Encoding や RLE といった論理エンコーディングを内部で施さないのが思想的な違いで、これがゼロコピー読み込みを成立させている。

v1 Feather は仕様が古く、近年は v2 (Arrow IPC) のみが推奨される。Pandas で df.to_feather() すると自動的に v2 で書き出される。

主な用途

  • Python ↔ R のデータ交換: Pandas で書いた .feather を、R の arrow::read_feather() で 1 行で読める。CSV/JSON 経由より圧倒的に速くて型も保たれる。
  • Jupyter Notebook での中間ファイル: 数百 MB の DataFrame をセル間や再起動を跨いで保持したいとき、pickle より互換性が高く読み込みが速い
  • 機械学習の前処理出力: 特徴量テーブルを学習プロセスに渡す。Parquet より起動が速いため、何度も読む小〜中規模データで強い。
  • プロセス間共有(shared memory): Arrow IPC Stream 形式 + Plasma Store などで、複数プロセス間でゼロコピー共有。
  • DuckDB / Polars との連携: 両者とも Arrow ネイティブなので、Feather/Arrow IPC をほぼ無コストで読める。

関連形式との比較

形式戦略サイズ読み込み速度得意
Feather / Arrow IPCメモリ表現直マッピング中〜大非常に高速言語間・プロセス間 I/O、中間ファイル
Parquet強圧縮・列指向速い(変換あり)長期保管・大規模分析
picklePython オブジェクト直列化速いPython 内のみ
CSVテキスト・行指向非常に遅い受け渡し

Wes McKinney 自身が「Parquet は長期、Feather は短期」と整理しており、これがそのまま選定指針になる。1 ヶ月以上保管するなら Parquet(Parquet(.parquet) 参照)、明日のセッションで読み直すだけなら Feather、というイメージ。

コマンド・ツール

Pandas (Python) から。

import pandas as pd
df = pd.DataFrame({"id": range(1000000), "v": [0.5]*1000000})

# 書き出し(自動的に Arrow IPC v2)
df.to_feather("data.feather")

# 読み込み
df2 = pd.read_feather("data.feather")

R から。

library(arrow)
df <- read_feather("data.feather")
write_feather(df, "out.feather")

pyarrow を直接使う場合は、RecordBatchFileWriter / RecordBatchFileReader でストリーミング処理も書ける。

import pyarrow as pa
import pyarrow.ipc as ipc

table = pa.table({"id": [1,2,3], "name": ["a","b","c"]})
with ipc.new_file("sample.arrow", table.schema) as w:
    w.write_table(table)

with ipc.open_file("sample.arrow") as r:
    print(r.read_all())

DuckDB からは SELECT * FROM 'data.feather' のようにそのまま SQL を投げられる。

注意点

  • 圧縮していないとサイズが大きい: Parquet の感覚で長期保管に使うとディスクを食う。長期保管は Parquet、それ以外で Feather と棲み分けるのが基本。
  • v1 と v2 の混在: 古い .feather は v1 で、機能・互換が限られる。新規書き出しはすべて v2 (Arrow IPC) になる。
  • 追記不可: 1 ファイル単発書き出しが基本。継続的に増えるログには向かない。
  • OS/エンディアン依存ではないが、Arrow バージョン非互換はたまに起きる。長期保管に使うなら pyarrow のバージョンを記録しておく。

関連リンク

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. SQL ダンプ(.sql)
  2. SQLite(.sqlite / .sqlite3 / .db)
  3. Parquet(.parquet)
  4. Avro(.avro)
  5. ORC(.orc)
  6. NDJSON / JSONL(.ndjson / .jsonl)
  7. BSON(.bson)
  8. Protocol Buffers(.proto)
  9. Feather / Arrow IPC(.feather / .ipc / .arrow)
  10. DB ダンプ(.dump / .bak)

最近更新/作成されたページ