科技小数据 Arrow:使用零内存读取DataFrame,Apache( 二 )


·文件查询/过滤器下推:在读入之前修剪不必要的数据 。 这可以缩短加载时间并优化资源消耗 。 如果您只需要一千个表格中的两列 , 则无需扫描所有行即可获得这两个属性-您可以直接获取整个列
压缩
为了更好地理解Parquet和Arrow之间的区别 , 我们将需要绕道而行 , 以进行压缩 。 文件压缩本身就是一个巨大的课题 。 以下是一个简化的叙述 , 通过我自己对该主题的理解而过滤掉了 。 题外话将帮助回答以下两个问题:
·Parquet如何将文件缩小到如此小的尺寸?
·Parquet与Avro有何不同?
掷硬币
假设您掷硬币十次并记录结果:
[Head,Head,Head,Head,Tail,Tail,Tail,Head,Tail,Tail]
现在 , 尝试大声说出结果吗?可能会缩短它 , 并说"4头 , 3尾 , 头和2尾" 。
[4xHead,3xTail,Head,2xTail]
这就是实际的压缩(所描述的算法称为游程长度编码[8]) 。 我们趋向于自然地看到一种模式并且缩写 。 压缩算法也可以做到这一点-只是具有更多的原始计算能力和复杂的规则 。 但是此示例足以帮助我们理解一个关键的区别:.csv采用文字方法并拼写出每条记录时 , Parquet则缩写(不丢失任何信息) 。
这个简单的例子足以说明为什么压缩率会大不相同 。 例如 , 如果排序顺序无关紧要 , 而您只是对头与尾的总出现次数感兴趣 , 则可以先对列表进行排序 , 然后压缩版本将如下所示:
[5xHead,5xTail]
言外之意 , 如果在将数据集保存到Parquet之前先按所有列对数据集进行排序 , 则文件大小将比未排序的数据集小 。 基数越低 , 压缩率越高 。 预期每列的压缩率将按排序顺序进一步缩小 。
Arrow被压缩了吗?
这样 , 我们就可以理解为什么Parquet文件与未压缩的.csv文件相比如此之小 。 但这与Arrow的关系如何?
事实证明 , 这恰恰是关键区别之一 。 Parquet以高效的方式存储在磁盘上 。 借助过滤器下推功能 , 您可以减少读入的数据量(即 , 仅选择您实际需要的列) 。 但是 , 当您要对数据执行操作时 , 计算机仍需要解压缩压缩后的信息并将其带入内存 。 [2]
另一方面 , Arrow是一种内存映射格式 。 WesMcKinney在博客文章中总结如下:
"Arrow序列化设计提供了一个'数据头' , 它描述了表中所有列的所有内存缓冲区的确切位置和大小 。 这意味着您可以在内存中映射比RAM更大的大型数据集 , 并就其评估Pandas式算法 , 而无需像现在对Pandas那样将其加载到内存中 。 您可以从1TB的表的中间读取1兆字节 , 而您只需支付执行总计1兆字节的那些随机读取的费用 。 "[6]
简而言之 , 应用程序可以直接对磁盘上存储的数据集进行操作 , 而无需将其完全加载到内存中 。 如果您还记得最初的Tweet , 那就恰好在这里 。
动手:性能比较
现在 , 让我们探索这些数据格式 。 作为示例数据集 , 我使用的是PalmerStationPenguin数据集 。 由于它仅包含350行 , 因此我将其重新采样为100万行 , 以使性能差异更加明显:
写文件
下一步 , 我将文件以三种格式写入磁盘:
·csv(缺少值的DataFrame)
·Parquet(缺少值的DataFrame)
·Arrow(具有&缺少值的DataFrame)
请注意 , 在某些情况下 , Arrow只能转换为Pandas , 而无需分配内存(=零副本) 。 其中之一:必须没有NaN值 。 为了比较使用零复制和不使用零复制之间的性能 , 我编写了一次包含和不包含缺失数值的Arrow文件 。
结果文件大小为:
科技小数据 Arrow:使用零内存读取DataFrame,Apache
文章图片
>Filesizecomparison
正如预期的那样 , Parquet是最小的文件-尽管是随机序列(在将文件写出之前未进行排序) , 但其压缩率高达80% 。 Arrow仅比csv小 。 原因是csv甚至将数值存储为字符串 , 这会占用更多磁盘空间 。 在所有情况下 , 具有缺失值和没有缺失值的文件之间的大小差异都很小(<0.5MB) 。


推荐阅读