ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Apache Arrow PyArrow Feather 文件格式详解:读写、压缩与向 Arrow IPC 迁移指南

Apache Arrow PyArrow Feather 文件格式详解:读写、压缩与向 Arrow IPC 迁移指南 Apache Arrow PyArrow Feather 文件格式详解读写、压缩与向 Arrow IPC 迁移指南【免费下载链接】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/arrowFeather 是 Arrow 项目早期为 Pythonpandas与 R 设计的跨语言数据帧存储格式其 V2 版本在磁盘上就是标准的 Arrow IPC 文件格式。本文基于官方文档docs/source/python/feather.rst结合pyarrow.feather模块的 Python/Cython/C 三层实现源码完整讲解 Feather 文件的读写 API、压缩配置、V1 遗留格式的局限与弃用状态以及如何平滑迁移到pyarrow.ipc与pyarrow.dataset帮助你在实际项目中正确选择存储格式并完成迁移。Feather 是什么两个版本两种形态根据官方文档 feather.rst 的定义Feather 是一种可移植的文件格式用于存储 Arrow Table 或来自 Python、R 等语言的数据帧DataFrame内部利用 Arrow IPC 格式实现。Feather 有两个版本V2默认版本在磁盘上恰好就是 Arrow IPC 文件格式本身。支持存储所有 Arrow 数据类型支持 LZ4 或 ZSTD 压缩。V2 自 Apache Arrow 0.17.0 起可用。V1遗留版本2016 年起可用的老版本已被 V2 取代。V1 文件与 Arrow IPC 文件是不同的文件结构缺乏许多特性例如不能存储所有 Arrow 数据类型且不支持压缩。自 25.0.0 起V1 文件的读写已被弃用deprecated将在未来版本中移除。一个容易混淆的细节是磁盘上的版本号与“Feather V1/V2”的对应关系。从 C 层源码 feather.h 可以看到static constexpr const int kFeatherV1Version 2; // 磁盘版本 2 Feather V1 static constexpr const int kFeatherV2Version 3; // 磁盘版本 3 Feather V2也就是说 Feather V1 文件在磁盘上写入的版本号是 2V2 文件的版本号是 3。这解释了 Python 读取端为何以version 3判定为 V1 文件见下文弃用告警部分。此外V1 文件头部使用独立的魔数FEA1见 feather.cc而 V2 文件则复用 Arrow IPC 的魔数——这也从文件格式层面印证了“V1 文件 distinct from Arrow IPC files”的说法。写入write_feather 完整参数与实现pyarrow.feather模块提供该格式的读写函数。write_feather接受pyarrow.Table或pandas.DataFrameimport pyarrow.feather as feather feather.write_feather(df, /path/to/file)完整函数签名为write_feather(df, dest, compressionNone, compression_levelNone, chunksizeNone, version2)各参数在 feather.py 中的定义与语义如下参数默认值说明df必填要写出的数据pandas.DataFrame或pyarrow.Tabledest必填本地目的路径或支持write的文件对象compressionNonezstd、lz4或uncompressed之一None时 V2 文件在 LZ4 可用时默认使用 LZ4否则不压缩compression_levelNone压缩器特有的压缩级别None使用压缩器默认级别chunksizeNone仅 V2 有效写入 Arrow IPC 时内部 RecordBatch chunk 的最大行数None使用默认值当前为 64K 行version2Feather 文件版本2 为当前版本1 为受限的遗留格式关于chunksize的 64K 默认值可在 C 层WriteProperties中找到对应定义chunksize 1LL 1665536 行注释说明“需要更快的随机行访问时应使用更小的 chunksize”见 feather.h。源码中的关键行为结合 feather.py 的实现有几点源码级事实值得注意V1 弃用告警传入version1时会立即抛出DeprecationWarning明确提示“Feather V1 files are deprecated as of 25.0.0”建议使用默认version2。DataFrame 索引处理输入是pandas.DataFrame时V1 走preserve_indexFalse不保存索引列V2 走preserve_indexNone交由Table.from_pandas默认策略。若传入其他版本号会抛出ValueError(Version value should either be 1 or 2)。V1 的硬性限制源码中逐一校验并抛错列名重复cannot serialize duplicate column names不支持压缩Feather V1 files do not support compression option不支持 chunksizeFeather V1 files do not support chunksize option转换到 Arrow 后若发生分块chunking则无法写入见check_chunked_overflowfeather.py其中 string/binary 类型单列超过 2GB 会明确报错。失败清理写入过程中若发生异常且dest是字符串路径会尝试删除已产生的残缺文件避免留下写一半的 Feather 文件。写入的最终落地路径是 Cython 层 _feather.pyx将compression字符串映射为 C 的CCompressionType_LZ4_FRAME/CCompressionType_ZSTD/CCompressionType_UNCOMPRESSED把version映射为kFeatherV2Version磁盘版本号 3或kFeatherV1Version磁盘版本号 2然后释放 GIL 调用 C 的WriteFeather。读取read_feather 与 read_tableread_feather将 Feather 文件读为pandas.DataFrameread_table读为pyarrow.Table。从实现看feather.pyread_feather内部就是先调用read_table再.to_pandas()转换# Result is pandas.DataFrame read_df feather.read_feather(/path/to/file) # Result is pyarrow.Table read_table feather.read_table(/path/to/file)两个读取函数都支持文件路径或文件对象with open(/path/to/file, wb) as f: feather.write_feather(df, f) with open(/path/to/file, rb) as f: read_df feather.read_feather(f)注意读入的文件对象必须支持 seekFeather/IPC 文件结构需要随机访问 footer 与 offset index。read_table(source, columnsNone, memory_mapFalse, use_threadsTrue)与read_feather(source, columnsNone, use_threadsTrue, memory_mapFalse, **kwargs)的关键参数columns只读取指定列可以是列名序列或列索引序列不传则读全部列memory_map当source为字符串路径时是否以内存映射方式打开文件适合大文件场景use_threads默认True是否用多线程并行化读取与 Arrow 到 pandas 的转换read_feather的**kwargs会透传给Table.to_pandas。列选择的实现细节内部函数_read_table_internalfeather.py揭示了几个具体行为打开文件后先判断reader.version 3即磁盘版本号为 2 的 V1 文件若是则发出DeprecationWarning建议改写为 IPCV2格式columns若为全 int 走read_indices全 str 走read_names混合类型会抛TypeError对 V2 文件若请求的列选择不是“已排序且去重”的形式读取后会再table.select(columns)以保持用户指定的原始列顺序。Cython 层的FeatherReader_feather.pyx直接封装 C 的CFeatherReader.Open并在nogil块内执行Read/Read(indices)/Read(names)即列裁剪发生在 C 底层而非先全量读出再过滤。多文件读取FeatherDatasetfeather.py 中的FeatherDataset类把多个 Feather 文件封装为一个整体dataset feather.FeatherDataset([part1.feather, part2.feather], validate_schemaTrue) table dataset.read_table(columns[col1]) df dataset.read_pandas(columns[col1], use_threadsTrue)其read_table逐个读取文件后concat_tables拼接validate_schemaTrue默认时会校验各文件 schema 完全一致不一致即抛出ValueError。官方文档明确指出对于多文件读取应改用pyarrow.dataset模块配合formatipc替代FeatherDataset——因为 V2 文件本身就是 IPC 文件用通用 Dataset 引擎可获得分区裁剪、谓词下推等更完整的读取能力。使用压缩自 Apache Arrow 0.17.0 起Feather V2 文件默认版本支持两种快速压缩库**LZ4frame 格式**和ZSTD。若通过常规包管理器安装了 pyarrow通常会带 LZ4 支持默认即使用 LZ4# Uses LZ4 by default feather.write_feather(df, file_path) # Use LZ4 explicitly feather.write_feather(df, file_path, compressionlz4) # Use ZSTD feather.write_feather(df, file_path, compressionzstd) # Do not compress feather.write_feather(df, file_path, compressionuncompressed)源码印证了默认行为合法压缩值集合为_FEATHER_SUPPORTED_CODECS {lz4, zstd, uncompressed}当compressionNone且Codec.is_available(lz4_frame)为真时才自动落到lz4feather.py。传其他值会抛ValueError。文档同时给出了压缩的实际收益结论默认的 LZ4 压缩通常能显著减小文件体积而不明显牺牲读写性能某些场景下由于减少了磁盘 IO 需求LZ4 压缩文件甚至比不压缩的文件读写更快。写入 Version 1 (V1) 文件已弃用deprecated: 25.0.0 — 遗留 Feather V1 格式的支持已弃用。 读写 V1 文件将在未来版本中移除。请将 V1 文件改写为 Arrow IPC 文件格式即 Feather V2。仅为兼容不支持 V2 文件的库时可以给write_feather传version1。如前所述V1 写入会触发DeprecationWarning且不支持压缩、不支持chunksize、不允许重复列名。建议能使用 V2 的一律使用 V2已有的 V1 文件可通过“读入会收到弃用告警→ 以 V2 重写”的方式迁移。迁移到 pyarrow.ipc官方文档给出了直接的替代路径既然 Feather V2 就是 Arrow IPC 文件格式可以用pyarrow.ipc模块作为直接替代feather.rstimport pyarrow as pa import pyarrow.ipc table pa.table({col1: [1, 2, 3], col2: [a, b, c]}) # Writing (replaces feather.write_feather) options pa.ipc.IpcWriteOptions(compressionlz4) with pa.ipc.new_file(data.arrow, table.schema, optionsoptions) as writer: writer.write_table(table) # Reading (replaces feather.read_table) with pa.ipc.open_file(data.arrow) as reader: result reader.read_all()这里有一个必须注意的默认值差异文档特别以 note 强调feather.write_feather默认 LZ4 压缩而ipc.new_file默认不压缩。要保持与 feather 相同的行为必须显式通过IpcWriteOptions传入compressionlz4如上例所示。pa.ipc.new_file与pa.ipc.open_file的接口定义见 ipc.py。在 C 侧这一迁移方向同样明确arrow::ipc::feather::Reader与WriteProperties均已标注在 26.0.0 弃用弃用信息直接指向替代方案——读用arrow::ipc::RecordBatchFileReader写用arrow::ipc::MakeFileWriterarrow::ipc::IpcWriteOptions见 feather.h 与 feather.h。Python 侧文档也承诺pyarrow.feather.write_feather与read_table的等价能力会在pyarrow.feather模块整体弃用前由pyarrow.ipc提供。小结与选型建议新写入一律使用 V2默认V2 即 Arrow IPC 文件支持全部 Arrow 类型与 LZ4/ZSTD 压缩跨语言互操作能力最强。V1 仅用于存量兼容25.0.0 起读写 V1 均已弃用且未来会移除V1 无压缩、无分块、类型受限遇到 V1 文件应尽快改写为 V2。长期方向是 pyarrow.ipc / pyarrow.datasetfeather模块的读写等价能力将由pyarrow.ipc承接多文件场景建议用datasetformatipc迁移时注意显式传IpcWriteOptions(compressionlz4)以保留 feather 的默认压缩行为。压缩默认开LZ4 frame 格式在可用时自动启用通常能在几乎不牺牲性能的前提下显著减小文件体积。关键源码参考python/pyarrow/feather.py、python/pyarrow/_feather.pyx、cpp/src/arrow/ipc/feather.h、cpp/src/arrow/ipc/feather.cc、python/pyarrow/ipc.py。【免费下载链接】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),仅供参考
返回列表