2013-04-15 3 views
3

У меня есть сжатый двоичный файл (bb2) bz2, содержащий массив данных. Распаковка его с внешними инструментами, а затем чтение файла, чтобы Numpy работы:Импортирование сжатого двоичного файла bz2 в виде массива numpy

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

Однако, так как есть много других файлов, как это я не могу извлечь каждый из них по отдельности заранее. Таким образом, я нашел модуль bz2 в Python, который мог бы непосредственно декомпрессировать его в Python. Однако я получаю сообщение об ошибке:

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

>>IOError: first argument must be an open file 

Очевидно, функция BZ2File не возвращает файл-объект. Знаете ли вы, как правильно читать сжатый файл?

ответ

5

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) 

(Излишне говорить, что есть множество других вариантов, которые могли бы быть лучше, чем чтение всего буфера в память Но если ваш файл не слишком большой, это будет работать.)

+0

frombuffer отлично работает, спасибо! – HyperCube

+0

'frombuffer()', похоже, не работает в python2.7. Он терпит неудачу с 'AttributeError: объект ExFileObject 'не имеет атрибута' __buffer __ ''. Любая идея почему? –

+0

Ничего, я использовал 'zipfl = bz2.BZ2File ('myfile.bz2'). Open ('file_memver_in_archive')', потому что я хотел получить 'dbuf.name' и другие атрибуты члена. Однако, если один из них требует, чтобы 'zipfl' был' ExFileObjcet', как и я, можно просто выполнить 'mydata = np.frombuffer (zipfl.read())' и иметь лучшее из обоих миров. –

Смежные вопросы