将 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
。
根据您的numpy
和python
版本以及您的平台,从不是实际文件的类文件对象读取可能无法正常工作。在这种情况下,您可以将读入的缓冲区与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 数组的主要内容,如果未能解决你的问题,请参考以下文章