且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

《Python和HDF 5大数据应用》——第1章 简介 1.1 Python和HDF5

更新时间:2022-09-12 20:18:24

本节书摘来自异步社区《Python和HDF 5大数据应用》一书中的第1章,第1.1节,作者[美]Andrew Collette(科莱特),胡世杰 译,更多章节内容可以访问云栖社区“异步社区”公众号查看。

第1章 简介

我刚毕业那会遇到过一个严重的问题——一部国家公认的等离子体研究设备花了整整一周时间收集的上千万个数据的值不太对劲。

比正常情况小了约40个数量级。

我跟我的咨询师挤在他的办公室,在一台崭新的G5 Mac Pro上运行我们的可视化软件,试图搞明白哪里出了问题。从机器中获得的数据是正确的,实验所使用的数字转换器提交的原始数据看上去没有问题。我在Thinkpad笔记本上用IDL语言编写了一个巨大的脚本将原始数据转换成可视化软件能够识别的文件。这些文件的格式十分简单:一个简短的定长头部后面加上一堆二进制浮点数据。我还另外又花了一个小时写了一个程序来验证这些文件,它们也没问题。但当我将所有这些在IDL中看上去如此优雅的数据导入可视化软件以后,它们看上去就像是一锅粥,毫无特色、杂乱无章,所有的值大约都只有10−41左右。

最后我们发现了问题所在:数字转换器和我的Thinkpad使用了“little-endian”格式,而G5 Mac使用了“big-endian”格式。一台机器输出的原始数据值无法被另一台机器正确地读入,反过来也一样。当时我所有想法中最有礼貌的一句是:这也太笨了。哪怕最后发现此类问题是如此司空见惯以至于IDL专门提供了一个SWAP_ENDIAN函数来处理也并没有令我的情绪变得更好。

在此之前我从不关心数据是如何存储的。这个事件以及其他一些类似事件改变了我的想法。作为一名科学家,我最终意识到,我们不仅需要选择数据的组织和存储,同时也需要选择数据的通信方式。设计优雅的标准格式不仅让每个人的生活变得简单(消除了上面愚蠢而又浪费时间的“endian”问题),而且也使得全世界都能共享这些数据。

1.1 Python和HDF5

在Python的世界里,人们在数值类型大数据的存储机制上进行选择时,迅速对层次性数据格式第5版(Hierarchical Data Format version 5,HDF5)达成了共识。当数据量越来越大的时候,数据的组织就变得越来越重要。命名数据集(第3章)、层次性分组(第5章)和用户自定义元数据“特征”(第6章)等HDF5特性对于数据分析的过程极为必要。

HDF5这种结构化的自我描述格式跟Python相辅相成。目前HDF5已经有两大开发成熟、功能丰富的Python接口模块h5py和PyTables,在两者之上还有许多为特定用途开发的小型封装模块。

1.1.1 数据和元数据的组织

这是一个利用HDF5的结构化能力帮助应用程序的简单例子。不要太担心文件结构和HDF5使用API等方面的细节,后续章节自会一一解释。就把这个当成是一次HDF5尝鲜。如果你想要运行这个例子,你需要Python 2并安装NumPy(第2章)。

假设我们有一个NumPy数组,它代表了某次实验获取的一些数据:

  

《Python和HDF 5大数据应用》——第1章 简介  1.1 Python和HDF5

假设这些数据来自某个气象站十秒一次的温度采样。为了让这些数据有意义,我们还需要记录采样的时间间隔“delta-T”。目前我们把它放到一个Python变量中。

  

《Python和HDF 5大数据应用》——第1章 简介  1.1 Python和HDF5

同时我们还需要记录第一个数据获取的时间起点,以及这些数据来自15号气象站:

  

《Python和HDF 5大数据应用》——第1章 简介  1.1 Python和HDF5

我们可以用一个简单的NumPy内建函数np.savez来将这些数据存入磁盘,该函数将每个数据以NumPy数组的格式保存并打包进一个指定名字的zip文件:

  

《Python和HDF 5大数据应用》——第1章 简介  1.1 Python和HDF5

我们可以用np.load从文件中获取这些数据:

  

《Python和HDF 5大数据应用》——第1章 简介  1.1 Python和HDF5

目前为止一切顺利。但如果每个气象站的数据不止一组怎么办?比如说还要记录一组风速数据?

 

《Python和HDF 5大数据应用》——第1章 简介  1.1 Python和HDF5

再假设我们有不止一个气象站。也许我们可以引入某种命名规范,比如“wind_15”作为15号气象站的风速数据,“dt_wind_15”作为采样时间间隔。又或许我们可以使用多个文件……

作为对比,让我们看看如果用HDF5来存储会是怎样:


《Python和HDF 5大数据应用》——第1章 简介  1.1 Python和HDF5

这个例子演示了HDF5的两个杀手级特性:层次性分组和特征。组就像文件系统里的目录,使你可以将相关的数据集保存在一起。本例将来自同一个气象站的温度和风速分别保存在名为“/15”和“/20”的组里。特征允许你在数据上直接附加描述性的元数据。一旦你将这个文件给其他同事,他们可以轻易发现这些信息并明白这些数据的意义:

《Python和HDF 5大数据应用》——第1章 简介  1.1 Python和HDF5

1.1.2 大数据复制

人们正在越来越多地将Python用于大数据集的快速可视化项目,在大规模计算中将Python作为一种高层粘合性语言来协助那些编译型语言如C和FORTRAN。现在一个数据集动不动就是上千GB甚至TB的数据需要处理,HDF5自身最大可以支持EB的规模。

大多数的机器不可能将如此大规模的数据集直接导入内存。HDF5最大的优点之一在于支持子集分片和部分I/O。让我们看一下之前创建的拥有1024个元素的“temperature”数据集:

  

《Python和HDF 5大数据应用》——第1章 简介  1.1 Python和HDF5

这里的dataset对象是一个HDF5数据集的代理对象。它支持数组切片操作,NumPy用户可能会觉得很熟悉:

  

《Python和HDF 5大数据应用》——第1章 简介  1.1 Python和HDF5

记住,真正的数据保存在磁盘上,切片操作会去寻找合适的数据并读入内存。这种形式的切片利用了HDF5底层的子集分片功能,所以非常迅速。

HDF5另一个伟大之处在于你可以控制存储的分配。当你创建了一个全新的数据集,除了一些元数据以外它不会占用任何空间,默认情况下仅当你真的需要写入数据时才会占用磁盘上的空间。

比如下面这个2TB的数据集,你可以在几乎任何计算机上创建出来:

 

 .《Python和HDF 5大数据应用》——第1章 简介  1.1 Python和HDF5

虽然还没有为其真正分配任何存储,但整个数据集的空间对我们都是可用的。我们可以在数据集的任何地方写入,而磁盘上只会占用必要的字节:

 

 《Python和HDF 5大数据应用》——第1章 简介  1.1 Python和HDF5

在存储非常昂贵的情况下,你甚至可以对数据集进行透明压缩(第4章):

 

 《Python和HDF 5大数据应用》——第1章 简介  1.1 Python和HDF5