---
title: "Parquetとは？読み方・仕組み・CSVとの違いとSnappy・Zstd圧縮の実測"
url: "https://www.issoh.co.jp/tech/details/5547/"
published: 2025-02-26
updated: 2026-10-18
categories: ["データ分析・BI"]
publisher: "株式会社一創"
---

# Parquetとは？読み方・仕組み・CSVとの違いとSnappy・Zstd圧縮の実測

Parquet（パーケイ）は、表形式のデータを列ごとにまとめて保存するファイル形式です。拡張子は `.parquet`。読み方は英語の辞書では「パーケイ」に近く、日本では「パーケット」とも呼ばれます。この記事では、読み方の根拠、CSVより速く小さくなる仕組み、Snappy・Zstd・Gzipのどれで圧縮するかを、100万行のデータで実測した数字とあわせて解説します。

## まとめ：Parquetの読み方と圧縮の選び方

- **読み方**：英語の発音は英米とも「パーケイ」（Cambridge Dictionary）、フランス語は「パルケ」。「パーケット」は床材の和製読みで、どれでも通じます。
- **正体**：Apache Software Foundationが管理する列指向のファイル形式。2013年にTwitterとClouderaが始め、2015年4月22日にApacheのトップレベルプロジェクトになりました。仕様の最新は parquet-format 2.14.0（2026年9月11日）。
- **CSVとの差**：100万行・7列の合成データの実測で、CSVの約43.0MBに対しParquet（Snappy）は約11.7MB、pandasでの全件読み込みは0.71秒に対し0.045秒でした。
- **圧縮の選び方**：迷ったらZstd。今回の実測ではSnappyより約27%小さく、書き込み時間の差は1割程度でした。同じ条件のGzipはZstdより大きく、書き込みは約23倍かかりました。
- **既定値はツールで違う**：pandas・PyArrow・Spark・DuckDBはSnappy、PolarsはZstd、AthenaのCTASはGZIP。出力ファイルの性格は指定しなかった既定値で決まります。
- **向かない用途**：1行ずつの更新・削除、人が直接編集するデータ、数KBの小ファイルを大量に作る運用。

## Parquetの読み方と語源

parquetはフランス語由来の英単語で、寄木張りの床を指します。辞書の発音は次のとおりで、末尾の t は発音しません。

| 言語    | 発音記号       | カナの目安       | 出典        |
| ----- | ---------- | ----------- | --------- |
| 英国英語  | /ˈpɑː.keɪ/ | パーケイ（前に強勢）  | Cambridge |
| 米国英語  | /pɑːrˈkeɪ/ | パーケイ（後ろに強勢） | Cambridge |
| フランス語 | \[parkɛ\]  | パルケ         | Larousse  |
| 日本の慣用 | ―          | パーケット・パーケ   | 床材の呼び名    |

英語の発音は[Cambridge Dictionaryの発音ページ](https://dictionary.cambridge.org/pronunciation/english/parquet)で、フランス語は[Larousseの辞書](https://www.larousse.fr/dictionnaires/college/parquet/29593)で確認できます。英語圏の会議や海外の同僚と話すなら「パーケイ」、社内で「パーケット」と呼ばれていても意味は通じます。Apache Parquetとして公式に定めた読みはありません。

## Parquetとは：列指向ファイル形式の成り立ちと現在の版

Parquetは、Hadoop向けの列指向ストレージとして2013年にTwitterとClouderaが共同で開発を始めた形式です。[parquet-formatのREADME](https://github.com/apache/parquet-format)には「Copyright 2013 Twitter, Cloudera and other contributors」とあり、入れ子のデータはGoogleのDremel論文のレコード分解（record shredding）の方式で列に分けると書かれています。

[Apache Incubatorの記録](https://incubator.apache.org/projects/parquet.html)では、2014年5月20日にIncubatorへ入り、2015年4月22日に卒業してトップレベルプロジェクトになりました。現在は仕様（parquet-format）と実装（Java版のparquet-java、C++版を含むApache Arrowなど）が別々に版を重ねています。

| 項目                   | 版      | 日付                 |
| -------------------- | ------ | ------------------ |
| 仕様 parquet-format    | 2.14.0 | 2026-09-11         |
| Java実装 parquet-java  | 1.18.1 | 2026-09-13（GitHub） |
| PyArrow（PyPI）        | 26.0.0 | 2026-10-09         |
| VARIANT・GEOMETRY型の追加 | 2.11.0 | 2025-03-23         |
| VARIANTの仕様確定         | 2.12.0 | 2025-08-28         |

最新の仕様版は[Parquet公式ブログの2.14.0リリース案内](https://parquet.apache.org/blog/2026/09/11/2.14.0/)で確認できます。2.11.0ではJSONのような半構造データを持つVARIANT型と、地理空間のGEOMETRY・GEOGRAPHY型が加わりました（[2.11.0のリリースノート](https://github.com/apache/parquet-format/releases/tag/apache-parquet-format-2.11.0)）。ただし新しい型は読む側のエンジンが対応していないと使えないので、受け渡し先の対応版を先に確かめてください。

## Parquetの仕組み：CSVより速く小さくなる理由

### 行指向と列指向の並べ方

CSVは「1,apple,100」「2,banana,120」と1行ずつ並べます。Parquetは「id列：1,2,3」「name列：apple,banana,orange」「price列：100,120,150」と列ごとにまとめます。price列の合計だけを出したいとき、CSVは全列を読んで区切り文字を解析しますが、Parquetはprice列の領域だけを読みます。同じ型の値が隣り合うので、圧縮も効きやすくなります。

### ファイル構造：行グループ・カラムチャンク・ページ・フッター

ファイルは数万〜数百万行ずつの**行グループ**に分かれ、行グループの中に列ごとの**カラムチャンク**、その中に圧縮の単位である**ページ**が入ります。通常の（フッターを暗号化していない）ファイルでは先頭と末尾に識別子 `PAR1` があり、末尾の**フッター**にスキーマ、列ごとの圧縮方式とエンコーディングが入ります。行グループ内の列ごとの最小値・最大値・NULL数といった統計も多くの実装が既定で書き込みますが、仕様上は任意で、PyArrowでは `write_statistics=False` で省けます。読む側はまずフッターを読み、必要な列と行グループの位置だけを取りに行きます。

行グループの大きさは書き込む側で決まります。[公式の設定ガイド](https://parquet.apache.org/docs/file-format/configurations/)は512MB〜1GBの大きな行グループを推奨し、PyArrowの既定は「テーブルの行数と1,048,576行の小さい方」です。今回の実測でも100万行は行グループ1つで書かれました。

### 読み飛ばしが効く条件：ソートの有無で実測

述語プッシュダウンは、WHERE句などの絞り込み条件をファイルを読む層まで渡す仕組みです。渡された条件と行グループの最小値・最大値を比べ、範囲外と分かった行グループは読まずに済みます。逆に、値がどの行グループにも散らばっていると、どの行グループも「該当するかもしれない」になり読み飛ばせません。100万行（日付180種類）を10万行ずつの行グループで書き、`date = '2026-03-01'` で絞り込んだ結果です。

| 書き方      | 先頭行グループのdate範囲   | 読む候補の行グループ | 読み込み時間（7回中央値） |
| -------- | ---------------- | ---------- | ------------- |
| ソートなし    | 2026-01-01〜06-29 | 10個中10個    | 21.2ms        |
| dateでソート | 2026-01-01〜01-18 | 10個中1個     | 6.6ms         |

返った行数はどちらも5,541行で同じです。ソートは必須ではなく、取り込み順で日付が自然にまとまっているデータなら並べ替えなしでも読み飛ばせます。ただ、今回のように値が散らばったデータでは、絞り込みに使う列（日付・テナントIDなど）で並べてから書くと読む行グループが減ります。Athenaなどスキャンしたバイト数で課金されるサービスでは、読み飛ばしで実際にスキャン量が減った分が料金に効きます（[Amazon Athena（アテナ）とは？使い方・クエリの書き方・料金・Redshiftとの違いを解説](/tech/details/4865/)）。

## ParquetとCSV・JSON・Avroの違い

乱数で作った100万行・7列の合成データ（ID、日付、カテゴリ、地域、ユーザーID、価格、小数）を、pandasでCSVとParquetに書き出し、どちらもpandasのDataFrameとして読み込む時間を5回測った中央値です。JSONとAvroは測っておらず、表は形式の性質だけを示しています。

| 項目        | CSV     | JSON  | Avro    | Parquet         |
| --------- | ------- | ----- | ------- | --------------- |
| 格納方式      | 行指向     | 行指向   | 行指向     | 列指向             |
| 形式        | テキスト    | テキスト  | バイナリ    | バイナリ            |
| 型・スキーマ    | なし      | 基本型のみ | あり      | あり              |
| 実測サイズ     | 約43.0MB | ―     | ―       | 約11.7MB（Snappy） |
| 実測の全件読み込み | 0.71秒   | ―     | ―       | 0.045秒          |
| 得意な処理     | 受け渡し    | API応答 | 1行ずつの追記 | 列の集計            |

書き出しはCSVが3.38秒、Parquetが0.24秒でした。JSONは文字列・数値・真偽値などの基本型を持ちますが、列の型を固定するスキーマは別に定義します。CSVは型を持たないので、読み込むたびに文字列を数値や日付へ変換する処理が入ります。Parquetは型を保ったまま保存するため、その変換が要りません。

AvroはKafkaのメッセージのように1件ずつ書き込む用途に向き、Parquetは溜めたデータを列単位で集計する用途に向きます。取り込みはAvroやJSONで受け、分析用にParquetへ変換する構成がよく使われます。人がExcelで確認する数百行のデータなら、CSVのままで困りません。

## Parquetの圧縮：Snappy・Zstd・Gzipを実測で比較

Parquetの圧縮は列（カラムチャンク）の中のページ単位でかかり、方式はフッターに列ごとに記録されます。読む側は方式を指定しなくても展開できます。仕様の[parquet.thrift（2.14.0）](https://raw.githubusercontent.com/apache/parquet-format/apache-parquet-format-2.14.0/src/main/thrift/parquet.thrift)が定めるコーデックは UNCOMPRESSED・SNAPPY・GZIP・LZO・BROTLI・LZ4・ZSTD・LZ4\_RAW の8つで、このうちLZ4は非推奨（DEPRECATED）です。

### コーデック別のサイズと書き込み・読み込み時間

前章と同じ合成データ100万行を PyArrow 26.0.0 の `write_table` で書き分け、書き込みと、pandasのDataFrameへの読み込みをそれぞれ5回測った中央値です（Intel Core i9-9880H・Python 3.13.14）。ほかの処理が動くマシンで測ったため、日をまたぐと絶対値は2倍前後ぶれました。同じ時点で測った相対差で見てください。

| compression | サイズ          | CSV比  | 書き込み   | 読み込み   |
| ----------- | ------------ | ----- | ------ | ------ |
| none        | 15,989,755 B | 37.2% | 0.38秒  | 0.066秒 |
| snappy（既定）  | 11,737,107 B | 27.3% | 0.41秒  | 0.061秒 |
| lz4         | 11,750,559 B | 27.3% | 0.40秒  | 0.061秒 |
| zstd        | 8,539,951 B  | 19.9% | 0.45秒  | 0.059秒 |
| brotli      | 8,566,537 B  | 19.9% | 2.52秒  | 0.039秒 |
| gzip        | 9,016,669 B  | 21.0% | 10.25秒 | 0.063秒 |

ZstdはSnappyより27%小さく、書き込みは0.41秒に対し0.45秒でした。Gzipはサイズで Zstd に負け、書き込みは約23倍かかっています。Zstdは `compression_level` で強さを変えられ、既定は level 1 と同じサイズでした。別の回の計測で level 19 まで上げると、サイズは2.7%縮む（8,314,084 B）一方、書き込み時間は level 1 の約18倍（0.84秒→15.18秒）になりました。書き込みの速さを優先するなら既定のまま、一度書いて長く保管・転送するデータなら高いレベルを試す価値があります。

PyArrowで `compression="lz4"` を指定すると、PyArrowのメタデータ表示は「LZ4」ですが、DuckDBの `parquet_metadata()` で生の値を見ると非推奨のLZ4ではなく `LZ4_RAW` で書かれていました。他のツールで書いたLZ4ファイルを受け取ったときは、どちらで書かれているかを確かめてください。

### 辞書エンコーディングの有無によるサイズ差

表の「none」でもCSVの37%まで縮んでいるのは、圧縮の前にかかるエンコーディングの効果です。PyArrowは既定で辞書エンコーディング（`RLE_DICTIONARY`）を使い、カテゴリや日付のような繰り返しの多い列を番号に置き換えます。`use_dictionary=False` で辞書を切ると、同じSnappyでも23,791,525 B（別の回の計測）になり、既定の約2倍でした。列ごとに見ると、5種類しかないcategory列は圧縮後379,389 Bで、ほぼ連番のorder\_id列（4,276,991 B）の1割以下です。想定よりファイルが大きいときは、コーデックを替える前に、書き込み側で辞書エンコーディングが切られていないか（`use_dictionary` の指定や、フッターの `encodings` に `RLE_DICTIONARY` があるか）を確かめてください。

### ツール別の既定コーデック

圧縮を指定しなかったときの既定値は、ツールごとに異なります。手元で同じデータを書き出し、フッターの記録で確かめた結果と公式ドキュメントの記載です。

| ツール                         | 既定     | 確認方法  |
| --------------------------- | ------ | ----- |
| pandas 3.0.6 to\_parquet    | SNAPPY | 実測・公式 |
| PyArrow 26.0.0 write\_table | SNAPPY | 実測・公式 |
| Apache Spark                | snappy | 公式    |
| DuckDB 1.5.6 COPY TO        | SNAPPY | 実測・公式 |
| Polars 2.0.0 write\_parquet | ZSTD   | 実測・公式 |
| Athena CTAS（Hiveテーブル）       | GZIP   | 公式    |
| Athena エンジン3のIceberg        | ZSTD   | 公式    |

Sparkの既定は[Sparkのドキュメント](https://spark.apache.org/docs/latest/sql-data-sources-parquet.html)の `spark.sql.parquet.compression.codec` が `snappy` で、Sparkが書いたファイル名の末尾が `.snappy.parquet` になるのはこのためです。Polarsの既定は[write\_parquetのリファレンス](https://docs.pola.rs/api/python/stable/reference/api/polars.DataFrame.write%5Fparquet.html)に `compression='zstd'` とあります。Athenaの[CTASの例](https://docs.aws.amazon.com/athena/latest/ug/ctas-examples.html)には「The default compression for Parquet is GZIP.」と書かれています。

行グループの切り方も違います。100万行（2列）を書くと、pandas・PyArrowは行グループ1つ、Polarsは12万5,000行ずつ8つ、DuckDBは12万2,880行単位で9つでした。Polarsの解説は[Polarsとは？pandasとの違い・高速化の仕組みと実務での採用判断【実装目線】](/tech/details/13618/)にまとめています。

### Snappy・Zstd・Gzipの選び方

- **新しく作るデータ**：Zstd。今回の実測ではSnappyより27%小さく、書き込み時間の差は1割程度、読み込みはほぼ同じでした。PolarsとAthenaのIcebergも既定をZstdにしています。
- **Snappyのままでよい場合**：受け渡し先に古いエンジンがあり、Zstdが読めるか確かめられないとき。Snappyはほぼ全ての実装が読めます。
- **Gzipは既存の受け渡し先が求めるときだけ**：今回の条件ではZstdより大きく、書き込みは約23倍かかりました。AthenaのCTASは既定がGZIPなので、Zstdにしたいときは `write_compression = 'ZSTD'` を明示します。Athena上の書き込み時間は今回測っていないので、効果は自分の環境で確かめてください（AthenaのParquetは[圧縮の対応表](https://docs.aws.amazon.com/athena/latest/ug/compression-support-hive.html)でZSTDの読み書きに対応）。
- **Brotli**：読み込みは最速でしたが、書き込みはZstdの約5.6倍です。一度書いて何度も読む配布用データなら候補になります。

## PythonでのParquetの読み書き（pandas・PyArrow）

pandasでParquetを読み書きするには、PyArrowかfastparquetのどちらかのエンジンが要ります。この記事の例はPyArrowを使います。pandasの基本は[Pandasとは？できること・使い方とPandas 3.0の変更点を解説](/tech/details/3123/)を参照してください。

```
pip install pandas pyarrow
```

`columns` で読む列を、`filters` で読む行を絞ります。`filters` は前章の行グループの読み飛ばしにも使われます。

```
import pandas as pd

df = pd.DataFrame({
    "id": [1, 2, 3, 4],
    "category": ["A", "A", "B", "B"],
    "price": [100, 120, 150, 180],
})

# 書き込み（compression を省略すると snappy）
df.to_parquet("sample.parquet", compression="zstd")

# 必要な列だけ・条件に合う行だけを読む
only = pd.read_parquet("sample.parquet", columns=["category", "price"],
                       filters=[("price", ">=", 150)])
print(only)
#   category  price
# 0        B    150
# 1        B    180
```

フッターに記録された行数・圧縮方式・統計値は、PyArrowの `metadata` で読めます。

```
import pyarrow.parquet as pq

md = pq.ParquetFile("sample.parquet").metadata
print(md.num_rows, md.num_row_groups, md.format_version)
# 4 1 2.6
col = md.row_group(0).column(2)          # price 列
print(col.compression, col.encodings)
# ZSTD ('PLAIN', 'RLE', 'RLE_DICTIONARY')
print(col.statistics.min, col.statistics.max, col.statistics.null_count)
# 100 180 0
```

`format_version` の 2.6 は、PyArrow 26.0.0 の `write_table` の既定 `version='2.6'` です（[write\_tableのリファレンス](https://arrow.apache.org/docs/python/generated/pyarrow.parquet.write%5Ftable.html)）。データページの形式は別の引数 `data_page_version` で、既定は ‘1.0’ です。「Parquet v2」と書かれているとき、どちらの話かは文脈で見分けてください。

## Parquetファイルの開き方と中身の確認

Parquetはバイナリなので、テキストエディタで開いても中身は読めません。手早く見るならDuckDBが便利で、ファイル名をそのままテーブルとしてSQLで読めます。Pythonから使う場合は先にDuckDBを入れます。

```
pip install duckdb
```

```
import duckdb

con = duckdb.connect()
print(con.sql("SELECT * FROM 'sample.parquet' LIMIT 5"))

# 行グループごとの圧縮方式と最小値・最大値
print(con.sql("""
  SELECT row_group_id, path_in_schema, compression,
         stats_min_value, stats_max_value
  FROM parquet_metadata('sample.parquet')
"""))

# CSVへ書き出す
con.sql("COPY (SELECT * FROM 'sample.parquet') TO 'sample.csv' (HEADER)")
```

`parquet_metadata()` の結果では、id・category・priceの3列それぞれに `ZSTD` と最小値・最大値（idは1と4、priceは100と180）が出ました。文字列の列の統計は `stats_min` 列だとNULLになるので、`stats_min_value` 列を見ます。CLIでも同じSQLが通ります。インストールから扱う手順は[DuckDBの使い方：インストールからCLI・Python・ファイル読み込みまでの手順【1.5.6対応】](/tech/details/15377/)を参照してください。

Excelで開きたいという質問は多いですが、Microsoftの[Power Queryコネクタの対応表](https://learn.microsoft.com/en-us/power-query/connectors/)では、ParquetはExcelの列が「No」で、Power BIとPower Query Onlineだけが対応です（2026年10月18日時点）。Excelで見る必要があるなら、上の `COPY` でCSVに書き出すか、Power BI Desktopで読み込みます。CSVに戻すと型の情報は失われるので、確認用の写しとして扱ってください。

## Parquetを使わない方がよい場面と運用の注意

Parquetのファイルは一度書いたら中身を書き換えられません。1行を更新するには、その行を含むファイルを丸ごと書き直します。注文ステータスのように1件ずつ頻繁に更新するデータはRDBに置き、分析用の写しだけをParquetにします。更新・削除・スキーマ変更の履歴をParquetの上で扱いたいなら、IcebergやDelta Lakeのようなテーブル形式を重ねます。違いは[Apache IcebergとParquetの違い｜テーブル形式とファイル形式の関係を整理](/tech/details/4812/)と[オープンテーブルフォーマットとは？Iceberg・Delta Lake・Hudiの違いと選び方を実装視点で解説【2026年版】](/tech/details/13784/)で整理しています。

もう一つの失敗は小さなファイルの大量発生です。ストリーミングで1分ごとに数KBのParquetを書くと、ファイルごとにフッターを読みに行く回数が増え、列指向の利点が消えます。公式は512MB〜1GBの行グループを推奨しているので、少なくとも数十MB以上にまとめてから書くか、定期的に結合する処理を入れてください。Sparkなら `coalesce` や `repartition` で出力ファイル数を減らせます。

列の型変更にも注意が必要です。過去のファイルでint32だった列を新しいファイルでint64にすると、エンジンによっては両方をまとめて読むときにエラーになります。データ基盤の設計から相談したい場合は、[データ分析基盤構築・MLOps構築支援](/service/ai/data-platform/)で承っています。

## よくある質問

### Parquetの読み方は？

英語の辞書（Cambridge）では英米とも「パーケイ」に近い発音で、フランス語では「パルケ」です。日本では床材の呼び名から「パーケット」とも読まれます。Apache Parquetとして公式に決めた読みはありません。

### Parquetの拡張子は？.snappy.parquet との違いは？

拡張子は `.parquet` です。`.snappy.parquet` はSparkなどが圧縮方式をファイル名に入れたもので、中身は同じParquetです。圧縮方式はファイル内のフッターに記録されているので、名前がどちらでも同じ方法で読めます。

### ParquetとCSVの違いは？

CSVは行ごとに並べたテキストで型を持ちません。Parquetは列ごとに並べたバイナリで型を持ちます。今回の100万行の合成データの実測では、Parquet（Snappy）はCSVの27%のサイズで、pandasでの全件読み込みは0.71秒に対し0.045秒でした。

### ParquetファイルはExcelで開ける？

Microsoftのコネクタ対応表では、ExcelのPower QueryはParquetに対応していません（2026年10月時点）。DuckDBなどでCSVに変換するか、Power BI Desktopで読み込みます。

### ParquetとIcebergの違いは？

Parquetはデータを入れる「ファイル形式」、Apache Icebergは多数のParquetファイルを1つのテーブルとして管理する「テーブル形式」です。競合ではなく、Icebergの中身としてParquetが使われる関係です。

## 関連記事

- [Apache IcebergとParquetの違い｜テーブル形式とファイル形式の関係を整理](/tech/details/4812/)
- [DuckDBの使い方：インストールからCLI・Python・ファイル読み込みまでの手順【1.5.6対応】](/tech/details/15377/)
- [オープンテーブルフォーマットとは？Iceberg・Delta Lake・Hudiの違いと選び方を実装視点で解説【2026年版】](/tech/details/13784/)
- [Amazon Athena（アテナ）とは？使い方・クエリの書き方・料金・Redshiftとの違いを解説](/tech/details/4865/)
- [Polarsとは？pandasとの違い・高速化の仕組みと実務での採用判断【実装目線】](/tech/details/13618/)

---

出典: [Parquetとは？読み方・仕組み・CSVとの違いとSnappy・Zstd圧縮の実測](<https://www.issoh.co.jp/tech/details/5547/>)（株式会社一創）
