parquet存储格式
parquet是一种列存储格式, 是 Apache 开源的一种列式存储文件格式主要用在大数据和机器学习的数据处理里。Spark、Pandas、PyArrow、DuckDB、Hugging Face Datasets 都能直接读写它。1. Intro**核心特点按列存储。**CSV、JSON 这类格式是一行一行存的Parquet 则把同一列的数据放在一起存。比如一张表有 id、text、score 三列行式存储的顺序是(1, hello, 0.9), (2, world, 0.8), ...列式存储的顺序是[1, 2, ...] [hello, world, ...] [0.9, 0.8, ...]列式存储的好处只读需要的列如果只要 score就不用把整列 text 从磁盘读出来I/O 大幅减少。压缩率高同一列的类型相同、值也相似配合字典编码、游程编码RLE再加上 Snappy、Zstd 等压缩算法文件通常比 CSV 小好几倍。自带 schema文件里记录了每列的类型比如 int64、string 或嵌套结构读的时候不用猜类型。可以跳过无关数据文件分成多个行组row group每个行组都存有统计信息比如每列的最小值和最大值。按条件过滤时可以直接跳过不可能有匹配行的行组。适合分布式处理一个大数据集通常切成很多个 Parquet 分片多个 worker 可以并行读取。缺点不适合频繁地单行更新或追加写入因为文件写完基本就不再改动。二进制格式不能像 CSV 那样直接用文本编辑器查看。2. row groups, column chunk和pageParquet 文件的结构分四层从外到内是文件File→ 行组Row Group→ 列块Column Chunk→ 页PageParquet 文件├── 魔数 “PAR1”├── Row Group 0│ ├── Column Chunk: id → Page, Page, …│ ├── Column Chunk: text → Page, Page, …│ └── Column Chunk: score → Page, Page, …├── Row Group 1│ └── …├── Footer元数据schema、各行组和列块的位置与统计信息└── 魔数 “PAR1”Row Group行组先把整张表按行横向切开。比如 1000 万行的数据可以分成 10 个行组每个row group 100 万行。row group内部再按列存储每一列的数据叫一个列块Column Chunk。所以 Parquet 实际上是先row group分组group内再按column存。这样既有列式存储的好处又不需要一次把整列都读进内存。row group的作用最小的并行和读取单位Spark、PyArrow 这类引擎通常按row group分配任务一个 worker 读一个或几个row group。用统计信息跳过数据footer 里记录了每个row group中每个column chunk的最小值、最大值和 null 数量。比如查询 score 0.95 时如果某个row group里 score 的最大值只有 0.8整个row group都可以直接跳过。决定内存占用写文件时一个row group的数据要先在内存里攒满才能写出去读的时候通常也是一次处理一个行组。row group大小怎么选太大比如几个 GB会导致读写内存占用高并行度也低。太小会让元数据变多、压缩率下降读取时随机 I/O 也更多。常见做法是让每个row group在 128MB 到 1GB 之间或者在几十万到一百万行左右。PyArrow 用 row_group_size 参数按行数控制。2.1. Page页每个column chunk又被切成若干页。页是编码和压缩的最小单位默认大小约 1MB。常见的页类型Data Page数据页存实际的列值以及处理 null 和嵌套结构用的 repetition/definition levels。Dictionary Page字典页如果某列用了字典编码列块开头会有一个字典页记录编号 → 真实值的映射。后面的数据页只存编号对重复值多的列比如 language、source压缩效果特别好。page的作用编码和压缩以页为单位读取时可以逐页解压不用一次解压整个列块。更细粒度的跳读较新版本的 Parquet 支持 Page Index记录了每个页的最小值和最大值。这样过滤时不仅能跳过行组还能在行组内部跳过页。各层职责层级怎么切分主要作用Row Group按行横切并行读取、按统计信息跳过、控制内存Column Chunk行组内按列只读需要的列Page列块内再切编码和压缩、更细粒度的跳读Footer文件末尾存 schema 和所有位置、统计信息读文件时最先读它meta data放在文件末尾是因为写文件时要等所有数据写完才知道每一块的位置和统计信息。所以读 Parquet 时会先读取文件结尾的 footer再按需定位到具体的行组和列块。Write a few rows to Parquet, then read them back in several ways.importpyarrowaspaimportpyarrow.computeaspcimportpyarrow.parquetaspq PATHdemo.parquetNUM_ROWS10ROW_GROUP_SIZE4# 1. 构造数据一列整数、一列文本、一列浮点、一列重复值多的类别rows[{id:i,text:fdocument number{i}lorem ipsum *(i1),score:round(i/NUM_ROWS,2),source:[web,books,code][i%3],}foriinrange(NUM_ROWS)]tablepa.Table.from_pylist(rows)print( 原始 schema )print(table.schema,\n)# 2. 写文件每 4 行一个行组数据页上限设得很小让列块被切成多个页pq.write_table(table,PATH,row_group_sizeROW_GROUP_SIZE,data_page_size64,# 字节默认约 1MBcompressionzstd,write_statisticsTrue,write_page_indexTrue,)# 3. 读元数据先读 footerpfpq.ParquetFile(PATH)metapf.metadataprint( 文件元数据 )print(f总行数{meta.num_rows}行组数{meta.num_row_groups}列数{meta.num_columns}\n)print( 每个行组 / 列块 )forrg_idxinrange(meta.num_row_groups):rgmeta.row_group(rg_idx)print(fRow Group{rg_idx}:{rg.num_rows}行,{rg.total_byte_size}字节(未压缩))forcol_idxinrange(rg.num_columns):colrg.column(col_idx)statscol.statisticsprint(f{col.path_in_schema:7}f编码{col.encodings}压缩后{col.total_compressed_size}B fmin{stats.min!r}max{stats.max!r}f有字典页{col.has_dictionary_page})print()# 4. 全量读取print( 全量读取 )print(pq.read_table(PATH).to_pandas(),\n)# 5. 只读一个行组的部分列print( 只读 Row Group 1 的 id 和 source )print(pf.read_row_group(1,columns[id,source]).to_pandas(),\n)# 6. 流式读取每批 3 行print( iter_batches(batch_size3) )forbatchinpf.iter_batches(batch_size3,columns[id,score]):print(f batch: id{batch.column(id).to_pylist()}score{batch.column(score).to_pylist()})print()# 7. 带过滤条件读取score 0.7 时Row Group 0 (max0.3) 可以直接跳过print( 过滤读取 score 0.7 )filteredpq.read_table(PATH,columns[id,score],filters[(score,,0.7)])print(filtered.to_pandas(),\n)# 8. 校验读回的数据与原始数据一致roundtrippq.read_table(PATH)assertroundtrip.equals(table),读回的数据和原始数据不一致assertpc.sum(roundtrip[id]).as_py()sum(range(NUM_ROWS))print(往返校验通过读回的数据与写入的完全一致)3. 常见用法3.1. 创建arrow arrayimportpyarrowaspaimportpyarrow.featherasfeatherimportpyarrow.parquetaspq arrpa.array([1,2,3,4,5])print(arr)输出[ 1, 2, 3, 4, 5 ]创建不同类型的array,arr_floatpa.array([1.0,2.5,3.0])arr_strpa.array([a,b,c])print(arr_float,arr_str)输出[ 1, 2.5, 3.0 ] [ a, b, c ]创建arrow table:tablepa.table({numbers:arr_float,letters:arr_str})print(table)输出:pyarrow.Table numbers: double letters: string ---- numbers: [[1,2.5,3]] letters: [[a,b,c]]3.2. 取数据, 做slice取列print(table[numbers])[ [ 1, 2.5, 3 ] ]取行print(table.slice(0,2))pyarrow.Table numbers: double letters: string ---- numbers: [[1,2.5]] letters: [[a,b]]3.3. 转pandas dataframeimportpandasaspd dftable.to_pandas()print(df)numbers letters 0 1.0 a 1 2.5 b 2 3.0 c3.4. 读写pyarrow文件pyarrow有2种文件格式:parquet (.parquet)Arrow IPC (.feather)Arrow IPC 和 Parquet 的核心区别在于Parquet 是为“长久存储和高压缩比”而设计的磁盘/归档格式Arrow IPC 是为“内存计算和进程间高速传输零拷贝”而设计的格式。两者在现代数据分析栈中通常是配合使用的关系即用 Parquet 存盘读入内存时直接转为 Arrow 格式进行计算。核心对比维度维度Arrow IPC (Inter-Process Communication)Apache Parquet主要定位内存布局的跨进程传输与共享格式长期存储与磁盘归档格式磁盘/内存一致性磁盘表示与内存布局完全一致磁盘表示与内存布局不同需解码/反序列化反序列化开销零拷贝 (Zero-copy)无需解码支持 mmap 内存映射即用即加载有解码开销必须解压、解编码并构建内存结构后才能计算压缩率与文件体积未压缩或仅轻微压缩如字典编码体积通常较大采用先进的列式压缩与编码算法体积小得多适用阶段Data in flight传输中 / 内存计算 / 进程间通信Data at rest静止状态 / 磁盘 / 长期持久化详细对比解析Apache Parquet专为“存盘”而生• 核心思想空间效率至上。Parquet 采用了高度优化的列式压缩、字典编码、RLE行程长度编码等技术把数据压缩得很小非常适合保存在硬盘上、对象存储如 S3或长期归档。• 代价当程序要读取 Parquet 数据进行计算时不能直接拿来就用必须经历解压、反序列化、组装成内存对象的过程这会消耗 CPU 和时间。• 了解更多可以参考 Apache Arrow FAQ 或 Apache Arrow 专栏解析。Arrow IPC专为“传输与计算”而生• 核心思想速度与零拷贝。Arrow IPC 的磁盘/传输格式与内存中的列式布局完全一致。• 优势• 零拷贝 (Zero-copy)接收方拿到数据后不需要反序列化直接把字节映射为内存指针即可使用。• 内存映射 (mmap)可以通过 mmap 直接打开一个 Arrow IPC 文件操作系统按需加载处理超大文件时进程内存开销极低。• IPC 类型分为 Stream 格式适合流式管道、顺序读写和 File 格式支持带 Footer 偏移量的随机访问。• 代价没有 Parquet 那么极致的压缩率文件通常比 Parquet 大。协作关系典型工作流在现代数据工程如 DuckDB、Pandas、Spark、PyArrow 等中两者的经典配合模式是静态存储数据以 Parquet 格式保存在磁盘或云端节省存储成本和网络传输带宽。内存计算读取 Parquet 文件时底层引擎直接将其解码/转换为 Arrow 内存格式例如 Python 中使用 pyarrow.parquet.read_table。高速交互/传输在不同进程、不同语言如 Python 传给 C 或 Java之间交换数据时使用 Arrow IPC 或 Arrow Flight 实现零拷贝极速传输。# writefeather.write_feather(table,table.feather)# read, 返回dataframetablefeather.read_feather(table.feather)print(table)# print(type(df)) # class pandas.core.frame.DataFrame# read, 返回arrowtablefeather.read_table(table.feather)print(table)print(type(table))# class pyarrow.lib.Tablepq.write_table(table,table.parquet)3.5. 查看schemaprint(table.schema)输出numbers: double letters: stringarrpa.array([1,None,2])print(arr)输出[ 1, null, 2 ]3.6 创建一个多个chunk的arraychunked_arrpa.chunked_array([[1,2,3],[4,5]])print(chunked_arr)print(fchunks:{chunked_arr.num_chunks})输出[ [ 1, 2, 3 ], [ 4, 5 ] ] chunks: 2往arrow table中添加数据t1pa.table({a:[1,2]})t2pa.table({a:[3,4]})combined_tablepa.concat_tables([t1,t2])print(combined_table)# pyarrow.Table# a: int64# ----# a: [[1,2],[3,4]]3.8. arrow与其他格式的zero-copy转换importnumpyasnp arrnp.array([1,2,3])pa_arrpa.array(arr)print(pa_arr)这里面没有发生内存拷贝Zero-copy零拷贝。为什么没有发生拷贝Apache Arrow 采用了精心设计的底层架构使其在处理特定的基本数据类型如整数 int、浮点数 float 等连续的原始数值类型时内存布局与 NumPy 数组完全一致。当你把这样一个一维 NumPy 数组传给 pa.array() 时PyArrow 会采用高度优化的代码路径直接让新生成的 pa_arr 去共享并指向原生 arr 的底层内存缓冲区Memory Buffer。这使得创建速度接近瞬时且几乎没有额外的内存开销。注意有些情况下会触发内存拷贝虽然你现在的代码是零拷贝但在以下几种 NumPy 转 Arrow 的常见场景中依然会触发内存拷贝包含缺失值NaN 或 None• NumPy 中的浮点数通常用 np.nan 表示缺失但没有原生的整数缺失值通常会转为 float。• Arrow 拥有独立的、基于位图Bitmap的 Null 值标记区域。如果 NumPy 数组中存在需要处理的 Null/NaN为了构建这层位图或调整对齐通常会产生拷贝。非连续的内存块Strided / Sliced Arrays• 如果你的 NumPy 数组经过了切片操作例如 arr base_arr[::2] 隔行取值其内存不再是连续的。由于 Arrow 数组要求底层数据必须完全连续此时 PyArrow 会强制进行拷贝将其重新压平组合。特定的复杂数据类型• 如果 NumPy 数组包含了 Python 对象类型dtypeobject、字符串类型、或某些多维结构Arrow 必须重新对齐和计算偏移量此时同样会引发内存拷贝。3.9. arrow to numpyimportnumpyasnp arrnp.array([1,2,3])pa_arrpa.array(arr)print(pa_arr)pa_arr.to_numpy()pyarrow不支持从nested list创建. 需要chunked_array才可以3.9 用schema创建schpa.schema([(a,pa.int64()),(b,pa.string())])table_with_schemapa.table([pa.array([1,2]),pa.array([a,b])],schemasch)print(table_with_schema)withpa.OSFile(file.parquet,rb)ass:tablepa.feather.read_table(s)print(table.shape)4. pyarrow数据处理创建数据# 1. Create sample data as Arrow Tableidspa.array([1,2,3,4,5])valuespa.array([5.2,6.3,7.1,8.4,9.9])scorespa.array([50,60,70,80,90])mini_tablepa.table({id:ids,value:values,score:scores})print(Sample data:)print(mini_table)Sample data: pyarrow.Table id: int64 value: double score: int64 ---- id: [[1,2,3,4,5]] value: [[5.2,6.3,7.1,8.4,9.9]] score: [[50,60,70,80,90]]过滤:# 2. Filter rows: Select rows with score greater than 60maskpa.compute.greater(mini_table[score],60)filteredmini_table.filter(mask)print(Rows with score 60:)print(filtered)Rows with score 60: pyarrow.Table id: int64 value: double score: int64 ---- id: [[3,4,5]] value: [[7.1,8.4,9.9]] score: [[70,80,90]]保存为文件# 3. Save and reload the filtered Table as Parquetpq.write_table(filtered,filtered.parquet)filtered_loadedpq.read_table(filtered.parquet)print(Reloaded filtered table:)print(filtered_loaded)

相关新闻

通信原理教学课件:27个可运行仿真+PPT内嵌实时动画

通信原理教学课件:27个可运行仿真+PPT内嵌实时动画

简介:本资源为《通信技术基础》完整版教学课件(第二版)电子讲义,面向高校通信工程、电子信息、计算机类专业师生及通信技术初学者,系统解决通信原理核心概念理解难、知识体系碎片化、理论与传输实践脱节等问题。课件以…

2026/10/18 14:25:32 阅读更多 →
我的编程课

我的编程课

2026/10/18 14:25:32 阅读更多 →
因子分析非正定矩阵:成因诊断与修复方案全解析

因子分析非正定矩阵:成因诊断与修复方案全解析

简介:这份文档资料聚焦因子分析中常见的非正定矩阵问题,面向使用SPSS进行多元统计分析的社科、经济、心理及医学领域研究者与数据分析学习者。资源以真实案例为主线,完整呈现某运营商无线增值业务31个省份、35个变量的因子分析过程&#xff0…

2026/10/18 14:24:31 阅读更多 →

最新新闻

Reflector 7.4.1.179 绿色注册版部署指南:插件集成与避坑实践

Reflector 7.4.1.179 绿色注册版部署指南:插件集成与避坑实践

简介:这是一份面向.NET开发者的反编译工具整合包,主角是经典的.NET Reflector 7.4.1.179绿色注册版,并真正集成了FileDisassembler与FileGenerator两款广受好评的插件,解决原版只能逐个查看方法、无法批量导出源码的痛点。包内共2…

2026/10/18 14:58:53 阅读更多 →
Vue权限控制实战:路由、菜单与按钮级权限完整链路

Vue权限控制实战:路由、菜单与按钮级权限完整链路

简介:这份资源面向正在开发后台管理系统的Vue前端开发者,聚焦权限控制这一核心场景,帮助解决不同角色用户只能访问被授权功能的问题。内容围绕两种主流限制方式展开:一是路由不可见,借助Vue Router的meta字段存储权限列…

2026/10/18 14:58:53 阅读更多 →
建筑施工安全技术资料如何变成项目台账?链路拆解与归档实操

建筑施工安全技术资料如何变成项目台账?链路拆解与归档实操

简介:建筑施工安全技术资料是现场安全管理的底账,而非应付检查的废纸。其核心原理是把方案、交底、检查、验收、整改五个环节串成管理链路,再按塔吊、基坑、临电等对象建立检索维度,形成“链路对象”的矩阵台账。通过统一编号、逐…

2026/10/18 14:58:53 阅读更多 →
YOLOv8骨干替换EfficientNetV2:均质架构提升小目标检测与推理性能

YOLOv8骨干替换EfficientNetV2:均质架构提升小目标检测与推理性能

1. 改造动机与方案选型1.1 YOLOv8原有骨干的瓶颈在哪里动手换主干之前,我先把YOLOv8原生CSPDarknet53的短板列了一遍。YOLOv8默认的backbone在COCO这类通用检测任务上确实够用,但一旦碰到分辨率高、小目标密集或纹理细节要求高的场景,它的问题…

2026/10/18 14:58:53 阅读更多 →
STM32F407 DCMI图像采集丢帧错位的硬件时序真相

STM32F407 DCMI图像采集丢帧错位的硬件时序真相

简介:本资源是一份基于STM32F407微控制器的高速并行12位ADC与DCMI数字摄像头接口协同开发实践方案,面向嵌入式初学者及图像采集方向进阶开发者,解决模拟信号高速采样与图像数据流同步传输的核心工程问题,适用于工业检测、智能视觉…

2026/10/18 14:58:53 阅读更多 →
《华为团队工作法》华为人才管理和薪酬激励:构建四位一体点燃员工热情的激励体系

《华为团队工作法》华为人才管理和薪酬激励:构建四位一体点燃员工热情的激励体系

本 115 页 PPT 适配企业人才管理、薪酬激励、干部管理类咨询方案与 HR 培训课件编制。基于华为人才管理体系核心实践,系统拆解人才选配、评估、干部任用、人才成长、文化锻造、薪酬激励、全面激励、健康成长八大模块。涵盖 STAR 行为面试、人才搭配四宫格、绩效能力…

2026/10/18 14:57:52 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →