Parquet 文件大于 Pandas DataFrame 的内存消耗

时间:2021-03-16 09:03:47

标签: python pandas parquet kedro

我将两个不同的 Pandas DataFrame 存储为镶木地板文件(通过 kedro)。

在写入磁盘之前,两个 DataFrame 具有相同的维度和数据类型 (float32)。此外,它们在 RAM 中的内存消耗是相同的:

distances_1.memory_usage(deep=True).sum()/1e9
# 3.730033604
distances_2.memory_usage(deep=True).sum()/1e9
# 3.730033604

当作为 .parquet 文件持久化时,第一个 df 生成一个 ~0.89GB 的文件,第二个文件生成一个 ~4.5GB 的文件。

distances_1 的冗余值比 distances_2 多得多,因此压缩可能更有效。

将 Parquet 文件从磁盘加载到 DataFrame 中会生成与原始 DataFrame 相同的有效数据。

  • 如何解释文件之间的巨大差异?
  • 第二个文件比内存中的数据结构大的原因是什么?

2 个答案:

答案 0 :(得分:2)

正如您所说,唯一值的数量对镶木地板的尺寸起着非常重要的作用。

从 Pandas 翻译过来,另外两个会对 Parquet 文件大小产生惊人影响的因素是:

  1. pandas 索引,即使它们只是自动分配的,也会默认保存;
  2. 数据的排序,这会对 Parquet 有时使用的游程长度编码产生很大差异。

无序的、自动分配的索引可能会占用大量空间。如果您不关心磁盘上数据的排序顺序,那么担心会产生很大的不同。

考虑 Pandas 框架的四种情况,其中一列在所有情况下都包含相同的数据:前 2**16 个整数的圆角正方形。在没有索引的情况下以排序形式存储它需要 2.9K;没有自动分配索引的 shuffled 需要 66K;自动分配索引然后改组需要 475K。

import pandas as pd
import numpy as np
!mkdir -p /tmp/parquet
d = pd.DataFrame({"A": np.floor(np.sqrt(np.arange(2**16)))})

d.to_parquet("/tmp/parquet/straight.parquet")
d.to_parquet("/tmp/parquet/straight_no_index.parquet", index = False)
d.sample(frac = 1).to_parquet("/tmp/parquet/shuf.parquet")
d.sample(frac = 1).to_parquet("/tmp/parquet/shuf_no_index.parquet", index = False)
ls -lSh /tmp/parquet
-rw-r--r--  1 user  wheel   475K Mar 18 13:39 shuf.parquet
-rw-r--r--  1 user  wheel    66K Mar 18 13:39 shuf_no_index.parquet
-rw-r--r--  1 user  wheel   3.3K Mar 18 13:39 straight.parquet
-rw-r--r--  1 user  wheel   2.9K Mar 18 13:39 straight_no_index.parquet

答案 1 :(得分:1)

从 Kedro 的角度来看,这只是调用 PyArrow 库 write_table 函数文件化 here。目录定义中的 save_args 参数可以使用这些参数中的任何一个,并且可能值得尝试一下?

相关问题