将 bz2 压缩二进制文件导入为 numpy 数组

Posted

技术标签:

【中文标题】将 bz2 压缩二进制文件导入为 numpy 数组【英文标题】:Importing bz2 compressed binary file as numpy array 【发布时间】:2013-04-15 09:52:55 【问题描述】:

我有一个包含数据数组的 bz2 压缩二进制(大端)文件。使用外部工具解压缩,然后将文件读入 Numpy 工作:

import numpy as np
dim = 3
rows = 1000
cols = 2000
mydata = np.fromfile('myfile.bin').reshape(dim,rows,cols)

但是,由于有很多其他类似的文件,我无法事先单独提取每个文件。因此,我在 Python 中找到了 bz2 模块,它可能可以直接在 Python 中解压它。但是我收到一条错误消息:

dfile = bz2.BZ2File('myfile.bz2').read()
mydata = np.fromfile(dfile).reshape(dim,rows,cols)

>>IOError: first argument must be an open file

显然,BZ2File 函数不返回文件对象。你知道读取压缩文件的正确方法是什么吗?

【问题讨论】:

【参考方案1】:

BZ2File 确实返回一个类似文件的对象(虽然不是一个实际的文件)。问题是你在上面调用read()

dfile = bz2.BZ2File('myfile.bz2').read()

这会将整个文件作为一个大字符串读入内存,然后您将其传递给fromfile

根据您的numpypython 版本以及您的平台,从不是实际文件的类文件对象读取可能无法正常工作。在这种情况下,您可以将读入的缓冲区与frombuffer 一起使用。

所以,要么这样:

dfile = bz2.BZ2File('myfile.bz2')
mydata = np.fromfile(dfile).reshape(dim,rows,cols)

……或者这个:

dbuf = bz2.BZ2File('myfile.bz2').read()
mydata = np.frombuffer(dbuf).reshape(dim,rows,cols)

(不用说,还有许多其他替代方法可能比将整个缓冲区读入内存更好。但如果您的文件不是太大,这将起作用。)

【讨论】:

frombuffer() 在 python2.7 中似乎不起作用。它以AttributeError: 'ExFileObject' object has no attribute '__buffer__' 失败。知道为什么吗? 没关系,我使用zipfl = bz2.BZ2File('myfile.bz2').open('file_memver_in_archive') 是因为我想获取dbuf.name 和成员的其他属性。但是,如果像我一样需要 zipfl 成为 ExFileObjcet,则可以简单地使用 mydata = np.frombuffer(zipfl.read()) 并拥有两全其美。 顺便说一句,直接使用 np.fromfile 到 bz2 文件,对我不起作用,但 np.frombuffer 工作正常。

以上是关于将 bz2 压缩二进制文件导入为 numpy 数组的主要内容,如果未能解决你的问题,请参考以下文章

Numpy用于数组的文件输入输出

Numpy | 23 IO

C 中的嵌入式 python:有没有办法从压缩的 python 存档中正确导入 numpy?

numpy的文件存储,读取 .npy .npz 文件

如何将 .sql.bz2 文件中的数据导入 hdfs?

如何将数组从.txt文件导入到numpy数组?