我将两个不同的Panda DataFrames存储为镶木地板文件(通过kedro(。
在写入磁盘之前,两个DataFrames都具有相同的维度和数据类型(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
多得多的冗余值,因此压缩可能更有效。
将镶木地板文件从磁盘加载到DataFrames中会产生与原始DataFrames相同的有效数据。
- 如何解释文件之间的巨大大小差异
- 为什么第二个文件会比内存中的数据结构大
正如您所说,唯一值的数量在镶木地板的尺寸中起着非常重要的作用。
从Panda翻译过来,另外两个因素可能会对拼花地板文件大小产生惊人的巨大影响,它们是:
- panda索引,即使只是自动分配,也会默认保存
- 数据的排序,这可能会对拼花有时使用的行程长度编码产生很大的影响
无序的、自动分配的索引可能会占用大量空间。如果您不关心磁盘上数据的排序顺序,那么担心这一点可能会产生重大影响。
考虑熊猫框架的四种情况,其中一列在所有情况下都包含相同的数据:前2**16个整数的四舍五入正方形。在没有索引的情况下以排序形式存储它需要2.9K;在没有自动分配索引的情况下进行混洗需要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
从Kedro的角度来看,这只是调用PyArrow库write_table
函数。这些参数中的任何一个都可以通过目录定义中的save_args
参数获得,是否值得一试?