目录
一、Parquet 文件数据说明
.parquet
是一种高效的列式存储格式,广泛用于大数据处理(如 Apache Spark、Dask、Pandas 等)。文件名 train-00001-of-00021.parquet
表示该文件是数据集的分片之一(共 21 个分片)。
1.Parquet 文件的核心特性
- 列式存储与行式存储(如 CSV)的区别:
- 行式存储:按行存储数据,适合事务型查询(如单行读取)。
- 列式存储:按列存储数据,适合分析型查询(如聚合统计、筛选部分列)。
- 优势:更高的压缩率(同列数据类型一致)、更快的列扫描速度。
- 支持复杂数据类型
- 可存储嵌套数据(如 JSON、数组、字典)。
- 支持高效编码(如字典编码、RLE 编码)和压缩(如 Snappy、GZIP)。
- 元数据与 Schema
- 文件末尾包含元数据(如 Schema 定义、列统计信息),便于快速读取。
- Schema 明确每列的数据类型(如
string
、int64
、binary
)。
2.文件分片说明
- 分片目的
- 并行处理:大数据集通常被切分为多个分片,便于分布式系统(如 Spark、Dask)并行读写。
- 内存优化:避免单个文件过大导致内存不足。
- 容错性:分片独立,部分失败可重试单个分片。
- 分片规则
- 分片数量(如
00021
)由数据量或用户配置决定。 - 分片大小通常均衡(如每个分片 100MB~1GB)。
- 分片数量(如
3.Parquet 文件结构
一个 Parquet 文件由以下部分组成:
- Header:文件标识(固定字符串
PAR1
)。 - Row Groups:数据按行组(Row Group)划分,每个行组包含多列。
- Column Chunks:每个列的数据块(含编码、压缩后的数据)。
- Footer:存储 Schema、行组元数据、分页索引等。
二、数据处理成 Parquet 文件
1.数据准备
- 数据内容,每个样本可能包含以下内容:
{
"image_id": "00001", # 文本字段
"image": bytes(...), # 二进制字段(图像字节流)
"text": "A cat sitting...", # 文本字段
"metadata": {"source": "web"} # 嵌套字段
}
- 数据格式:可能是 JSON、CSV 或内存中的结构化数据(如 Pandas DataFrame)。
2.选择工具
- Apache Spark(分布式处理,适合超大数据集)。
- PyArrow/Pandas(单机处理,适合中小数据集)。
- AWS Glue/Google BigQuery(云服务)。
3.写入 Parquet
- 以 PyArrow/Pandas 为例:
import pandas as pd
import pyarrow.parquet as pq
# 示例数据(假设已加载到 DataFrame)
df = pd.DataFrame({
"image_id": ["00001", "00002"],
"image": [bytes(...), bytes(...)], # 图像二进制数据
"text": ["text1", "text2"]
})
# 单分片写入
df.to_parquet("data.parquet", engine="pyarrow")
# 分片写入(生成 21 个分片)
pq.write_to_dataset(
pyarrow.Table.from_pandas(df),
root_path="output_dir",
partition_cols=None, # 可选按列分区
row_group_size=10000, # 行组大小
max_partitions=21 # 分片数量
)
4.分片策略
- 按行数分片:如每 10 万行一个分片。
- 按大小分片:如每 500MB 一个分片。
- 按列分区:如按日期分区(需指定
partition_cols
)。
5.验证 Parquet 文件内容
- 使用
parquet-tools
(需安装)查看元信息:
parquet-tools inspect train-00001-of-00021.parquet
- 输出示例:
File path: train-00001-of-00021.parquet
Creator: parquet-cpp-arrow version 12.0.0
Schema:
image_id: BYTE_ARRAY String
image: BYTE_ARRAY Binary
text: BYTE_ARRAY String
metadata: STRUCT<source: BYTE_ARRAY String>
--- Row Group 0 ---
Rows: 10000
- 使用Python读取:
import pandas as pd
df = pd.read_parquet("train-00001-of-00021.parquet")
print(df.head())
三、Parquet 文件解析
1.安装必要的库
pip install pandas pyarrow # 安装 Pandas + PyArrow(推荐组合)
# 或
pip install fastparquet # 替代方案(FastParquet)
2.读取单个 Parquet 文件
import pandas as pd
# 读取单个文件
file_path = "train-00001-of-00021.parquet"
df = pd.read_parquet(file_path, engine="pyarrow") # engine可选 "pyarrow" 或 "fastparquet"
# 查看数据前几行
print(df.head())
# 查看列名和数据类型
print(df.columns)
print(df.dtypes)
3.合并多个分片文件
- 如果数据集分片存储在多个
.parquet
文件(如train-0000x-of-00021.parquet
),可以通过以下方式合并:
import glob
import pandas as pd
# 获取所有分片文件路径
file_pattern = "train-*-of-00021.parquet"
file_list = sorted(glob.glob(file_pattern)) # 按文件名排序
# 逐个读取并合并(适用于小数据集)
combined_df = pd.concat(
[pd.read_parquet(file) for file in file_list],
ignore_index=True
)
# 查看合并后的数据
print(combined_df.shape)
4.处理大型数据集(内存不足时)
- 如果数据量过大,直接合并可能导致内存溢出,建议以下方法:
- 方法 1:分批处理
for file in file_list:
chunk = pd.read_parquet(file)
# 处理单个分片(如保存到磁盘或逐步计算)
- 方法 2:使用 Dask(分布式计算库)
# pip install dask[dataframe]
import dask.dataframe as dd
# 读取所有分片(惰性加载,不立即加载到内存)
ddf = dd.read_parquet("train-*.parquet", engine="pyarrow")
# 执行计算(如保存为 CSV 或导出统计结果)
ddf.compute().to_csv("combined_data.csv")
5.解析数据内容
-
RealSyn15M 数据集包含图文对数据,查看列名和数据类型为:Index([‘raw_image_url’, ‘text1’, ‘text2’, ‘text3’, ‘syn_text’], dtype=‘object’),请读取分片文件、解析数据内容并将前100行数据写入csv文件。
-
RealSyn15M 数据结构:
-
RealSyn15M 分片数据:
import pandas as pd
# 读取单个分片文件(例如 train-00001-of-00021.parquet)
file_path = "train-00001-of-00021.parquet"
df = pd.read_parquet(file_path, engine="pyarrow") # 使用 PyArrow 引擎
# 提取前 100 行
top_100 = df.head(100)
# 保存为 CSV(假设列名是 ['raw_image_url', 'text1', 'text2', 'text3', 'syn_text'])
output_csv = "output.csv"
top_100.to_csv(output_csv, index=False, encoding="utf-8") # 不保存索引列
print(f"已保存前 100 行数据到 {output_csv}")