高效快速保存 Pandas DataFrame – Parquet vs Feather vs ORC vs CSV

张开发
2026/4/5 9:23:05 15 分钟阅读

分享文章

高效快速保存 Pandas DataFrame – Parquet vs Feather vs ORC vs CSV
原文towardsdatascience.com/saving-pandas-dataframes-efficiently-and-quickly-parquet-vs-feather-vs-orc-vs-csv-26051cc98f2e优化https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/5b7873414756f7492ea83c93b3e8c248.png混合数据的输出文件大小 – 作者图像随着产生的数据量的不断增长不可避免地需要高效且快速地存储和重新加载这些数据。CSV 长期以来一直是首选的支柱。然而有许多更好的替代方案专门设计用来直接处理表格数据的存储和高效重新加载。那么如果你仍然使用 CSV 格式存储数据表你将失去多少你应该考虑哪种替代方案简介当涉及到存储表格数据时理想的情况是快速写入快速阅读低内存使用低存储需求压缩选项良好有一个选项可以只读取部分数据而不必加载整个数据集这将是对上述内容的绝佳补充。因此上述列表将构成测试一些更广泛使用的方法对这些因素的基线。具体来说CSVFeatherParquetORC存储方法的简要概述本节将简要概述本文中将使用的每种存储方法。这是一个简单的入门没有更多。CSVhttps://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/0fd6f94ee77f218b92d7a72ab48b9164.png由Mika Baumeister在Unsplash上的照片CSV逗号分隔值可能是仍然存储表格数据最广泛使用的方法之一。正如其名所示每一行是一系列由逗号分隔的值。每个逗号分隔符表示一个新列每行的新行表示一个新行。非常简单。没有一种简单的方法可以读取部分数据特别是关于列的数据。因此通常必须读取所有数据才能访问存储数据的小部分。此外尽管“逗号分隔值”这个名字暗示了一个一致的标准但实际上并非如此。半角分号、制表符甚至空格经常被用作分隔符。不提及其他潜在的不一致性如字符编码和标题行的处理。所有这些都使得实现高效且可重复的编码和解码方法变得更加困难。Featherhttps://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/bba59d38bfc680c7e2787ebb394a7785.png由 Jenelle 在 Unsplash 拍摄的照片Feather 文件格式 是…这是一个用于存储 Arrow 表或数据框来自 Python 或 R 等语言的可移植文件格式它内部使用 Arrow IPC 格式。Feather 是在 Arrow 项目早期创建的作为为 Python (pandas) 和 R 提供快速、语言无关的数据框存储的证明概念。Feather 有两种文件格式版本–arrow.apache.org事实上它是一个二进制格式用于保存原始的 Arrow 数据Apache Arrow 定义了一种与语言无关的列式内存格式用于平面和分层数据旨在在现代硬件如 CPU 和 GPU上进行高效的分析操作。Arrow 内存格式还支持零拷贝读取以实现闪电般的数据访问而无需序列化开销。–arrow.apache.org从本质上讲它满足了众多条件只能读取特定列即列式存储格式多线程GPU 使用压缩zstd 或 lz4Parquethttps://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/8c03056c5777333b1dc49f96a7b36a4a.png图片由 Gerd Altmann 提供来自 PixabayApache Parquet 是…这是一个开源的、面向列的数据文件格式旨在高效地存储和检索数据。它提供了高性能的压缩和编码方案以处理大量复杂数据并且被许多编程语言和数据分析工具所支持。–parquet.apache.org可以公平地说Parquet 比 Feather 更“功能丰富”这里就不详细说明了并且在大数据领域通常被更广泛地使用。然而在基本使用层面上它们相当相似。只能读取特定列即列式存储格式多线程GPU 使用压缩snappy、gzip、brotli、lz4 和 zstdORC (优化行列式)https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/87e6e6990ffc191f077e02e6963d6700.png图片由 Jim Cooper 提供来自 Pixabay这是一个有趣的特点。大约在 2013 年与 Parquet 同时发布ORC是另一种基于列的文件格式。它已被 Facebook 等大型机构采用甚至有如下说法Facebook 使用 ORC 在他们的数据仓库中保存数十 PB并证明 ORC 比 RC File 或 Parquet显著更快。–orc.apache.org现在应该注意的是ORC 通常与Hadoop和Hive一起使用因此在我们这里更基本的用法中将很有趣地看到与 Parquet 和 Feather 相比会发生什么。只能读取特定列即列式存储格式多线程GPU 使用情况压缩snappyzliblz4 和 zstd计划计划基本上是使用 Pandas 库对这些不同的存储方法进行实际比较。主要比较比较将基于五个因素最终保存的文件大小写入速度读取速度读取时使用的 RAM写入时使用的 RAM这将适用于所有格式以及该特定文件格式可用的所有压缩方法CSV– 无压缩bz2gziptarxzzipzstdFeather– 无压缩lz4zstdParquet– 无压缩brotligziplz4snappyzstdORC– 无压缩lz4snappyzlibzstd**注意**所有压缩算法都将使用 Pandas 默认设置的设置。在某些情况下可以进行微调但本文不会涉及这一点。进一步调查自 Pandas 2 发布以来可以使用 PyArrow 数据类型在 DataFrame 中而不是 Pandas 1 版本中标准的 NumPy 数据类型。我们还将了解 Pandas 2.0 中可用的新的 PyArrow 数据类型是否会产生影响…这在保存和读取数据时会产生影响吗我们将找出答案。数据为各种测试生成了虚拟数据。它故意选择较大的数据量导致保存为纯 CSV 时 DataFrame 的大小约为 2GB。此外还将调查数据类型的混合DataFrame 1 – 混合浮点数字符串和布尔值100000 行和 1200 列未压缩 CSV – 2.27GB分别有 400 列的浮点数字符串和布尔值DataFrame 2— 仅浮点数100000 行和 1200 列未压缩 CSV – 2.18GB从 0 到 100 的随机均匀分布中提取floats_arraynp.random.default_rng().uniform(low0,high100,size[rows,cols])DataFrame 3— 仅字符串100000 行和 600 列未压缩 CSV – 1.98GB字符串被生成为一个 MD5 哈希用于浮点数数组中的浮点数任何存在的7都将被空格替换。**注意**此 DataFrame 的列数是先前 DataFrames 的一半因为字符串占用更多空间。然而最终文件大小大致相同。string_array[:,i]df_floats.iloc[:,i].apply(lambdax:hashlib.md5(str(x).encode(utf-8)).hexdigest().replace(7, )).to_numpy()DataFrame 4— 仅布尔值100000 行和 6000 列未压缩 CSV – 3.30GBbool_arraynp.random.choice(a[False,True],size(rows,cols))***注意*这个 DataFrame 的列数比之前的 DataFrame 多得多因为布尔值不占用太多空间。最终文件大小实际上比之前的 DataFrame 大 50%。测试平台为了透明起见这是运行本文中所有测试的计算机的配置CPU– Intel i7–4790KRAM– 20GB所有测试都保持在 RAM 内没有使用交换空间GPU– EVGA GeForce GTX 1070 FTWSSD– WD SN850 1TBNVMeOS– Arch Linux这应该会在查看结果时提供一个大致的基准。测试 – 混合数据初始时测试将很广泛并展示所有方法与混合数据集浮点数 字符串 布尔值之间的比较。然后我们将深入到后续部分中表现最好的格式的更具体测试。***注意*一般来说所有 RAM 统计信息和读写时间都会因在实时系统上测试而略有变化。特别是关于 RAM结果通常是可靠的因为我能够通过系统应用程序监控实际使用情况作为比较。任何小的或负的 RAM 使用值基本上可以视为零。所有方法 – 文件大小 – 混合数据https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/5b7873414756f7492ea83c93b3e8c248.png保存的文件大小– 所有方法 – 编写测试 – 图像由作者提供在生成文件大小方面如果使用压缩方法似乎所有格式都是相对可比的。然而如果你打算完全不使用压缩方法使用除 CSV 以外的任何格式显然是一个显著的优势。让我们看看读写速度和 RAM 使用情况是否会改变这一情况。所有方法 -执行时间 – 混合数据https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/440c20d824dedad3defb3e91c07b6385.png执行时间– 所有方法 – 编写测试 – 图像由作者提供https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/a91a4436cbb7cfa4635f3780e4541eab.png执行时间– 所有方法 – 读取测试 – 图像由作者提供执行时间正是 CSV 开始显示出其低效的地方。如此之低效以至于在排除 brotli 和 gzip 的 parquet 测试之外通常至少比其他所有方法慢四倍来写入并且至少慢两倍来读取。如上简要提到的brotli 和 gzip 算法在写入速度方面也极其缓慢。所有方法 – RAM 使用 – 混合数据https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/19622c7bf446de61e16601665aff66fb.pngRAM 使用– 所有方法 – 编写测试 – 图像由作者提供https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/6ace03578f878dda8c2c2cfd821fc03b.pngRAM 使用– 所有方法 -读取测试 – 图像由作者提供RAM 使用情况很有趣。CSV 表现非常好。如果你有非常严格的 RAM 要求而执行时间不是问题这一点值得注意。然而这里有一些值得注意的结果。未压缩的 feather 在读写方面都是顶级表现者。在压缩方面feather 和 orc 在读写方面表现相似。parquet 通常在写入方面表现优异但在某些情况下在读取操作中过度使用 RAM。混合数据 – 总结考虑到混合数据的所有因素实际上有一些非常有趣的结果。CSV 应该被忽略与其他方法相比CSV 几乎没有使用价值主要因为与其他方法相比执行速度极慢。唯一的例外是如果你有非常严格的 RAM 要求。ZSTD 是优越的压缩方法从结果中可以非常明显地看出无论使用哪种文件类型ZSTD 都是出色的压缩方法。无论你查看哪个指标它都表现良好。它具有一些最高的压缩比率同时执行速度快并且使用相对较小的 RAM 量。继续…在接下来的几节中我们将更深入地探讨具体细节。CSV 也不会出现因为我认为它已经出局了。这也使图表更清晰具体来说以下将予以考虑数据类型是否重要将分别测试充满浮点数、字符串和布尔值的 DataFrame以查看这与混合数据相比如何。Pandas 2.x 包含使用 “PyArrow” 数据类型的可能性。这与迄今为止使用的 “Numpy” 数据类型相比如何数据类型是否重要从上一节的第一点开始让我们找出在 DataFrame 中使用特定数据时任何文件格式是否有任何优势或劣势。文件大小https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/06136d4a5f0dff1b8647618a409a1b85.png保存的文件大小– 混合数据 – 作者提供的图像https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/dff4087e293126db67939d6f698d63d0.png保存的文件大小– 浮点数据 – 作者提供的图像https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/1c85f5a377546cd4c9431bd12869c05f.png保存的文件大小– 字符串数据 – 作者提供的图像https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/6f9c72acaab89ef8632aed2e63aed2e8.png保存的文件大小– 布尔数据 – 作者提供的图像在文件大小方面ZSTD 在所有方面都具有优越的压缩比率。ORC 处于领先地位但实际上 feather 和 parquet 大致相当唯一的例外是处理浮点数据时的 parquet。执行速度 – 写入https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/c6ea37988d178a5d3cee50891577f6af.png执行时间– 写入 – 混合数据 – 作者提供的图像https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/b190d0bcec771fbc46380f6e06f11ddb.png执行时间– 写入 – 浮点数据 – 图像由作者提供https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/8189f003c236c19925d2a35063593a63.png执行时间– 写入 - 字符串数据 – 图像由作者提供https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/71f6d56cb090dc413759733e872cba22.png执行时间– 写入 – Boolean data – 图像由作者提供写入速度非常有趣。最引人注目的是feather 的速度至少是其他方法的两倍有时甚至更快。与 feather 相比布尔数据似乎对 ORC 和 parquet 来说是一个特别的问题。浮点数据再次似乎是对 parquet 的弱点对于 ORC 而言关于布尔数据也是如此。这是一个真正的混合体但 feather 的胜利是令人信服的。读取速度https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/afc9e6ba305f9b44302d3686a5d4e4df.png执行时间– 读取 – Mixed data – 图像由作者提供https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/6eccb8845ad9a440c0ad849b277c3dda.png执行时间– 读取— 浮点数据 – 图像由作者提供https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/9be2fd0bf768cedc633fda2469d5412f.png执行时间– 读取 – 字符串数据 – 图像由作者提供https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/dde883514c59566d910c8cfe6bc75514.png执行时间– 读取 – Boolean data – 图像由作者提供总体而言读取时间在不同文件类型和所有数据类型之间相当快且一致。feather 在各方面都有轻微的优势但并不极端。RAM 使用 – 写入https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/76c23b24e1375ff171c95d6c69ecef32.pngRAM 使用– 写入 – Mixed data – 图像由作者提供https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/94b63d09b67c957a8a65b64c167cf264.pngRAM 使用– 写入 -Float data – 图像由作者提供https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/fa9587f83b1d5ac0b723427f2ff3cf7d.pngRAM 使用– 写入 – 字符串数据 – 图像由作者提供https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/ebd4ede2ebdfd18b5e335570e75de01d.pngRAM 使用– 写入 – Boolean data – 图像由作者提供在写入时的 RAM 使用方面对于所有文件类型字符串数据是一致的。然而当涉及到浮点或布尔数据时使用 parquet 或未压缩的 feather 会有显著的优势。ORC 在 RAM 写入使用方面确实略逊一筹。RAM 使用 – 读取https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/20deab82da95bf6fa305a75348220f6d.pngRAM 使用– 读取 – Mixed data – 图像由作者提供https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/653115a5309ee919e90105257a30b5ca.pngRAM 使用– 读取 -Float data – 图像由作者提供https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/2998611eb828769993935aa8be7c992e.pngRAM usage– Read -String data – Image by authorhttps://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/28b1a938198fe39ac6bc7fc12777b51e.pngRAM usage– Read -Boolean data – Image by author读取时的 RAM 使用情况相当复杂所有文件类型的表现大致相当。对于某些情况例如未压缩的羽毛数据它根本不占用任何 RAM以及在使用 ORC 时浮点数据都有例外。Pandas 2.x with PyArrow DatatypesPandas 2 的发布带来了一个显著的升级即直接在 DataFrames 中利用 PyArrow 数据类型的能力。例如如果我要使用 numpy 数据类型加载一个 feather 文件df_numpypd.read_feather(dataframe.feather.zstd,dtype_backendnumpy_nullable)…或者我可以使用新的 PyArrow 后端并加载 PyArrow 数据类型df_pyarrowpd.read_feather(dataframe.feather.zstd,dtype_backendpyarrow)由于一些格式如 parquet 和 feather在某种程度上基于 PyArrow这为大幅提高性能提供了潜力。让我们看看这实际上会产生什么样的差异。PyArrow Comparison由于 ZSTD 压缩在整个文章中一直优于所有其他压缩方法下一组比较将仅使用 ZSTD 作为压缩。https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/9e647096c3957720881f2879260f2027.png保存的文件大小– 混合数据 – Image by author如预期的那样保存的文件大小之间没有差异因此让我们转向执行时间。Execution timehttps://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/e83254e4375e8529fa5486e70a5f254b.pngExecution time– Write **** – Mixed data – Image by authorhttps://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/59fc6a988949e87a0b67d84f88752a2b.pngExecution time– Read **** – Mixed data – Image by author很明显在读取和写入时间上使用 PyArrow 数据类型都有显著优势。这尤其是在 ORC 和 feather 文件格式中它们的速度至少是使用 numpy 数据类型时的两倍。RAM usagehttps://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/64492d78c0f1e5ab0aa2ebdeb84db886.pngRAM usage– Write **** – Mixed data – Image by authorhttps://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/0dfab19695b4efa27674650dc45d6812.pngRAM usage– Read **** – Mixed data – Image by authorRAM 使用情况相当复杂在写入时具有显著优势但在读取性能上略差。快速分析https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/9f453f5b6c9f871168f6f0223aa2f9ac.pngImage by Gerd Altmann from Pixabay通常来说CSV 可以被丢弃。唯一的真正例外是如果你的特定用例中内存非常有限在这种情况下执行速度的严重劣势可能值得考虑。通常来说CSV 可以被丢弃然而通常这取决于 feather、ORC 和 Parquet 之间的选择。FeatherFeather 通常是一个非常好的选择。它在读写速度上相当一致地优于其他格式尤其是在不使用压缩的情况下对内存的使用方面。[Feather] 在读写速度上相当一致地优于其他格式Feather 通常被认为比其他格式功能较少但显然如果执行速度和内存是首要考虑因素的话它显然值得考虑。ORCORC 也是顶级性能者。它在某些类别上并不完全优于 feather但足够接近具有相关性。更重要的是它在所有条件下都一致地产生最高的压缩比使用 ZSTD。[ORC] 始终产生最高的压缩比如果你的目标是最终的压缩比同时在其他方面牺牲不多那么 ORC 是一个不错的选择。ParquetParquet 通常被认为是一个比 feather 功能更丰富的版本并且在工业界得到广泛应用。它的性能与 ORC 非常相似有时略好有时略差。尽管我会说 ORC 在整体上略有优势。[Parquet] 的性能与 ORC 非常相似再次强调如果你的特定用例确实需要 Parquet 的特定功能那么它绝对值得考虑。结论https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/bd0e9733cb451fd4a8a3ab5fc98f1a09.png由 Anna Tarazevich 在 Pexels 上拍摄的照片为了保持简单这是基于本文结果我推荐的做法只有在你拥有的数据在读写时会导致内存问题的情况下才使用 CSV如果可能始终使用 PyArrow 数据类型而不是 numpy 数据类型总是使用 ZSTD 压缩因为它在压缩的同时也很快Feather 通常表现最好所以如果可能的话使用它如果你需要 Parquet 或 ORC 的附加功能那么使用其中之一与 feather 相比你不会失去任何显著的东西。如果你不能使用 feather但可以自由选择 ORC 和 Parquet那么选择 ORC因为它通常性能略好。记住本文中的结果仅针对文章中早些时候指定的数据。你可能发现对于更大的或更小的 DataFrame结果可能与这里展示的不同。然而我希望你现在已经拥有足够的数据量以便做出明智的决定选择最适合你特定情况的格式。

更多文章