数据存储与解析:深度剖析 Parquet 文件处理全流程

一、Parquet 文件数据说明

.parquet 是一种高效的列式存储格式,广泛用于大数据处理(如 Apache Spark、Dask、Pandas 等)。文件名 train-00001-of-00021.parquet 表示该文件是数据集的分片之一(共 21 个分片)。

1.Parquet 文件的核心特性

  • 列式存储与行式存储(如 CSV)的区别
    • 行式存储:按行存储数据,适合事务型查询(如单行读取)。
    • 列式存储:按列存储数据,适合分析型查询(如聚合统计、筛选部分列)。
    • 优势:更高的压缩率(同列数据类型一致)、更快的列扫描速度。
  • 支持复杂数据类型
    • 可存储嵌套数据(如 JSON、数组、字典)。
    • 支持高效编码(如字典编码、RLE 编码)和压缩(如 Snappy、GZIP)。
  • 元数据与 Schema
    • 文件末尾包含元数据(如 Schema 定义、列统计信息),便于快速读取。
    • Schema 明确每列的数据类型(如 stringint64binary)。

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}")
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

探模之翼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值