
PyArrow Parquet 数据类型处理read_dictionary、binary/list 类型选择、扩展类型读取与时间戳存储【免费下载链接】arrowApache Arrow is the universal columnar format and multi-language toolbox for fast data interchange and in-memory analytics项目地址: https://gitcode.com/GitHub_Trending/arrow3/arrow在 PyArrow 中读写 Parquet 文件时Arrow 类型与 Parquet 逻辑类型并非一一对应同一份字节数据既可以读作StringArray也可以读作DictionaryArrayBYTE_ARRAY列既可以是 32 位偏移的binary也可以是 64 位偏移的large_binary时间戳则涉及 ms/us/ns 多种分辨率与 INT96 这一已弃用格式。本文基于 PyArrow 官方文档 数据类型处理指南结合仓库中 Parquet 核心实现 的源码系统讲解read_dictionary、binary_type/list_type、arrow_extensions_enabled、coerce_timestamps等选项的用法、默认行为与源码实现细节帮助你在控制内存占用与保证跨框架兼容性之间做出正确选择。以 DictionaryArray 读取read_dictionary 选项read_table与ParquetDataset提供的read_dictionary选项会让指定列以DictionaryArray形式读取转换为 pandas 时会变成pandas.Categorical。该选项只对字符串string与二进制binary列有效对于重复字符串值较多的列可以显著降低内存占用并提升处理性能。官方文档给出的完整示例如下 import pyarrow as pa import pyarrow.parquet as pq table pa.table({one: [-1, None, 2.5], ... two: [foo, bar, baz], ... three: [True, False, True]}) ... pq.write_table(table, example.parquet) pq.read_table(example.parquet, read_dictionary[two]) pyarrow.Table one: double two: dictionaryvaluesstring, indicesint32, ordered0 three: bool ---- one: [[-1,null,2.5]] two: [ -- dictionary: [foo,bar,baz] -- indices: [0,1,2]] three: [[true,false,true]]从源码结构看这一选项在两条读取路径上都有支持pq.read_table的函数签名直接接收read_dictionary参数见 read_table 定义底层会将其传入 Parquet 读取器ParquetDataset的构造函数同样接收read_dictionary并在内部将其映射为 dataset 层ParquetFileFormat的dictionary_columns参数见 ParquetDataset.init中的参数映射。也就是说无论是单文件读取还是多文件数据集扫描read_dictionary都是通过同一个ParquetFileFormat读取选项生效的两者行为一致。实际应用中典型场景是读取 Hive 分区表时把低基数的分类列如category、region声明为字典列避免在 Arrow 内存中为每行存储完整字符串副本。读取 binary 与 list 列binary_type 与 list_type默认情况下Parquet 的BYTE_ARRAY列读作 Arrowbinary类型ParquetLIST列读作 Arrowlist类型二者都使用32 位偏移量。对于超大列累计长度超过约 2GB 或子元素数超过约 20 亿32 位偏移会发生溢出。binary_type和list_type两个读取参数允许你在读取时指定不同的 Arrow 类型。binary_type接受pa.binary()默认、pa.large_binary()或pa.binary_view() table pa.table({data: pa.array([bhello, bworld], pa.binary())}) pq.write_table(table, binary.parquet, store_schemaFalse) pq.read_table(binary.parquet, binary_typepa.large_binary()).schema data: large_binarylist_type接受pa.ListType或pa.LargeListType table pa.table({lists: pa.array([[1, 2], [3]], pa.list_(pa.int32()))}) pq.write_table(table, lists.parquet, store_schemaFalse) pq.read_table(lists.parquet, list_typepa.LargeListType).schema lists: large_listelement: int32 child 0, element: int32需要特别注意一个前提当 Parquet 文件元数据中已序列化保存了 Arrow schema即写文件时使用store_schemaTrue时binary_type和list_type两个设置都会被忽略因为读取端会直接采用文件中记录的类型信息。因此上面示例中的write_table特意传了store_schemaFalse让文件只保留 Parquet 原生 schema从而使读取端可以自由选择 32 位或 64 位偏移类型。以 Arrow 扩展类型读取arrow_extensions_enabled某些 Parquet 逻辑类型JSON、UUID、Geometry、Geography默认会被读作 Arrow扩展类型extension type分别对应arrow.json、arrow.uuid和geoarrow.wkb。这一行为由arrow_extensions_enabled参数控制并作用于pyarrow.parquet.read_table、ParquetFile、ParquetDataset以及read_schema四类入口。如果想把这些逻辑类型读作普通存储类型storage type——这是 PyArrow 21.0.0 之前版本的默认行为——只需设置pq.read_table(example.parquet, arrow_extensions_enabledFalse)在源码中ParquetDataset.__init__的arrow_extensions_enabled参数默认值为True并直接透传给ds.ParquetFileFormat的读取选项见 ParquetDataset 构造与参数映射其 docstring 也明确写道“If True, read Parquet logical types as Arrow extension types where possible, (e.g., read JSON as the canonicalarrow.jsonextension type or UUID as the canonicalarrow.uuidextension type)”。一个额外依赖需要留意将 GEOMETRY/GEOGRAPHY 列读作geoarrow.wkb时还要求geoarrow.wkb扩展类型已经被注册。做法是安装 GeoArrow 的 Python 绑定包geoarrow-pyarrow并导入geoarrow.pyarrow模块注册完成后geoarrow.wkb扩展类型才会在读取时生效。时间戳的存储coerce_timestamps 与 INT96时间戳是 Parquet 类型处理中最容易踩坑的部分根源在于不同实现支持的分辨率不同。分辨率差异与默认行为部分 Parquet 读取端只支持毫秒ms或微秒us分辨率的时间戳。由于 pandas 内部使用纳秒表示时间戳直接写入时可能遇到兼容性问题。官方文档说明默认情况下写 version 1.0 的 Parquet 文件时纳秒时间戳会被 cast 为微秒us。而当前仓库中 Parquet 写入参数的 docstring 给出了更精确的规则version参数取值为{1.0, 2.4, 2.6}coerce_timestamps默认None此时根据version选择默认策略version1.0与version2.4下纳秒会 cast 为usversion2.6下纳秒原样无损写入秒级时间戳无论何种版本默认都会被 cast 为ms因为 Parquet 不存在秒级时间类型若 cast 到更低分辨率会丢失数据默认会抛出异常除非显式传入allow_truncated_timestampsTrue。使用coerce_timestamps选择目标分辨率 pq.write_table(table, example.parquet, coerce_timestampsms)如果 cast 可能导致数据丢失默认会抛出异常可传入allow_truncated_timestampsTrue抑制该异常 pq.write_table(table, example.parquet, coerce_timestampsms, ... allow_truncated_timestampsTrue)注意 docstring 中的一条细节约束allow_truncated_timestampsTrue只有在coerce_timestamps不为None时才会实际生效单独传它而不指定目标分辨率并不能绕过截断异常。纳秒无损存储Parquet 格式版本 2.6使用较新的 Parquet 格式版本 2.6 可以不做任何 cast 直接存储纳秒时间戳 pq.write_table(table, example.parquet, version2.6)但正如官方文档提醒的许多 Parquet 读取端尚不支持这个较新的格式版本因此在需要跨不同处理框架兼容的场景下推荐显式使用version1.0以获得最大文件兼容性。当前源码 docstring 同样强调“Files written with version2.4 or 2.6 may not be readable in all Parquet implementations, so version1.0 is likely the choice that maximizes file compatibility。”见 写入参数说明已弃用的 INT96 时间戳格式较老的 Parquet 实现采用INT96存储时间戳该格式现已弃用——但一些老版本 Apache Impala 与 Apache Spark 依赖它。为了与这类系统互通可以在write_table中将use_deprecated_int96_timestamps设为True pq.write_table(table, example.parquet, use_deprecated_int96_timestampsTrue)从 ParquetWriter 参数处理逻辑 可以确认其默认语义use_deprecated_int96_timestamps默认为None即由flavor参数决定——指定flavorspark时自动置为True适配 Spark 的兼容需求否则为False并且该选项优先于coerce_timestampsdocstring 原文“This take priority over the coerce_timestamps option”。关键参数速查参数作用对象默认值说明read_dictionary读取read_table/ParquetDatasetNone指定以DictionaryArray读取的列名列表仅对 string/binary 列有效binary_type读取pa.binary()BYTE_ARRAY列的 Arrow 类型可选pa.large_binary()、pa.binary_view()文件含 Arrow schema 时失效list_type读取pa.ListTypeLIST列的 Arrow 类型可选pa.LargeListType文件含 Arrow schema 时失效arrow_extensions_enabled读取True是否将 JSON/UUID/Geometry/Geography 逻辑类型读作扩展类型arrow.json/arrow.uuid/geoarrow.wkbversion写入2.6docstring可用值{1.0, 2.4, 2.6}跨框架兼容建议显式version1.0coerce_timestamps写入None按 version 自动目标分辨率有效值{None, ms, us}秒级时间戳默认 cast 为msallow_truncated_timestamps写入False允许时间戳 cast 丢失精度而不抛异常需与coerce_timestamps同时指定use_deprecated_int96_timestamps写入None随 flavor 决定写 INT96 时间戳已弃用flavorspark时自动启用优先于coerce_timestamps小结与延伸阅读本文覆盖的四个主题恰好对应 Parquet 与 Arrow 类型体系之间的四道“映射关口”字符串/二进制列的编码形态read_dictionary、偏移位宽binary_type/list_type、逻辑类型语义arrow_extensions_enabled与时间分辨率coerce_timestamps、version、INT96。掌握这些选项后你可以针对内存敏感的重复值列、超 2GB 的二进制/列表列、需要扩展类型语义的 JSON/UUID 列以及纳秒级时间戳分别采取正确的读写策略。相关源码与文档入口PyArrow Parquet Python 核心模块read_table、read_schema、ParquetDataset、写入参数实现与 docstringParquet 模块入口对外暴露的 API 汇总本文对应的官方 RST 文档PyArrow 文档站“Parquet — Data Type Handling”一节的源文件。【免费下载链接】arrowApache Arrow is the universal columnar format and multi-language toolbox for fast data interchange and in-memory analytics项目地址: https://gitcode.com/GitHub_Trending/arrow3/arrow创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考