Чтение двоичного файла с использованием numpy fromfile в сочетании с lzma open

У меня есть двоичный файл, содержащий значения типа double (64-битные данные с плавающей запятой). Использование numpy fromfile

>>> data1 = numpy.fromfile(open('myfile', 'rb'))

Я получаю правильные данные (я получаю те же данные с data1 = numpy.fromfile('myfile'))

>>> data1
array([  1.29000000e-07,   3.70000000e-08,   3.80000000e-08,
     3.70000000e-08,   3.60000000e-08,   3.80000000e-08,
     3.80000000e-08,   3.70000000e-08,   3.80000000e-08,
     3.60000000e-08,   3.80000000e-08,   3.70000000e-08,
     3.60000000e-08,   3.60000000e-08,   3.80000000e-08,
     3.50000000e-08,   3.80000000e-08,   3.80000000e-08,
     3.80000000e-08,   3.60000000e-08,   3.70000000e-08,
     3.60000000e-08,   3.70000000e-08,   3.70000000e-08,
     3.60000000e-08,   3.50000000e-08,   3.70000000e-08,
     3.70000000e-08,   3.60000000e-08,   3.50000000e-08,
     3.80000000e-08,   3.80000000e-08,   3.60000000e-08,
     3.50000000e-08,   3.90000000e-08,   3.70000000e-08,
     3.70000000e-08,   3.70000000e-08,   3.50000000e-08,
     3.70000000e-08,   3.60000000e-08,   3.70000000e-08,
     3.80000000e-08,   3.90000000e-08,   3.90000000e-08,
     3.60000000e-08,   3.60000000e-08,   3.70000000e-08,
     3.60000000e-08,   3.80000000e-08,   3.70000000e-08,
     3.50000000e-08,   3.50000000e-08,   3.60000000e-08,
     3.60000000e-08,   3.70000000e-08,   3.50000000e-08,
     3.70000000e-08,   3.60000000e-08,   3.80000000e-08,
     3.80000000e-08,   3.80000000e-08,   3.80000000e-08,
     3.90000000e-08,   3.90000000e-08,   3.50000000e-08,
     3.80000000e-08,   3.80000000e-08,   3.70000000e-08,
     3.70000000e-08,   3.60000000e-08,   3.80000000e-08,
     3.60000000e-08,   3.70000000e-08,   3.70000000e-08,
     3.80000000e-08,   3.60000000e-08,   3.60000000e-08,
     3.50000000e-08,   3.80000000e-08,   3.60000000e-08,
     3.70000000e-08,   3.60000000e-08,   3.80000000e-08,
     3.50000000e-08,   3.80000000e-08,   3.70000000e-08,
     3.60000000e-08,   3.70000000e-08,   3.90000000e-08,
     3.60000000e-08,   3.60000000e-08,   3.90000000e-08,
     3.80000000e-08,   3.60000000e-08,   3.60000000e-08,
     3.70000000e-08,   3.70000000e-08])

Теперь я сжимаю этот файл, используя xz

xz -k myfile

а затем попробуйте прочитать данные в python с помощью модуля lzma

>>> data2 = numpy.fromfile(lzma.open('myfile.xz'))
>>> data2
array([  2.05244522e-289,   3.09873319e-303,  -9.10852154e-136,
     9.99900586e-150,  -7.22647881e+061,  -3.03508634e-168,
     1.40409926e+097,  -8.66961452e+219,   2.28992199e-308,
    -7.28706929e+173,   1.41101250e+029,  -2.94590886e-279,
     7.21680144e+171,  -4.62715868e+045,   3.05536517e-138,
    -2.94268247e-043,  -1.54563603e-295,   7.53024241e+102,
    -1.22865109e+263,   2.62485731e+044,   4.52556260e-312,
     1.18164036e-240,   3.56496646e-311,  -2.82751232e+286,
     1.69336097e+127])

Почему это происходит? Просмотр содержимого файлового объекта через read дает

>>> open('myfile', 'rb').read()
b'B$\xf7\xffgP\x81>\x1c\xe8l\xc4=\xddc>\xd1\x1e\xae#\xaefd>\x1c\xe8l\xc4=\xddc>g\xb1+e\xcdSc>\xd1\x1e\xae#\xaefd>\xd1\x1e\xae#\xaefd>\x1c\xe8l\xc4=\xddc>\xd1\x1e\xae#\xaefd>g\xb1+e\xcdSc>\xd1\x1e\xae#\xaefd>\x1c\xe8l\xc4=\xddc>g\xb1+e\xcdSc>g\xb1+e\xcdSc>\xd1\x1e\xae#\xaefd>\xb3z\xea\x05]\xcab>\xd1\x1e\xae#\xaefd>\xd1\x1e\xae#\xaefd>\xd1\x1e\xae#\xaefd>g\xb1+e\xcdSc>\x1c\xe8l\xc4=\xddc>g\xb1+e\xcdSc>\x1c\xe8l\xc4=\xddc>\x1c\xe8l\xc4=\xddc>g\xb1+e\xcdSc>\xb3z\xea\x05]\xcab>\x1c\xe8l\xc4=\xddc>\x1c\xe8l\xc4=\xddc>g\xb1+e\xcdSc>\xb3z\xea\x05]\xcab>\xd1\x1e\xae#\xaefd>\xd1\x1e\xae#\xaefd>g\xb1+e\xcdSc>\xb3z\xea\x05]\xcab>\x85U\xef\x82\x1e\xf0d>\x1c\xe8l\xc4=\xddc>\x1c\xe8l\xc4=\xddc>\x1c\xe8l\xc4=\xddc>\xb3z\xea\x05]\xcab>\x1c\xe8l\xc4=\xddc>g\xb1+e\xcdSc>\x1c\xe8l\xc4=\xddc>\xd1\x1e\xae#\xaefd>\x85U\xef\x82\x1e\xf0d>\x85U\xef\x82\x1e\xf0d>g\xb1+e\xcdSc>g\xb1+e\xcdSc>\x1c\xe8l\xc4=\xddc>g\xb1+e\xcdSc>\xd1\x1e\xae#\xaefd>\x1c\xe8l\xc4=\xddc>\xb3z\xea\x05]\xcab>\xb3z\xea\x05]\xcab>g\xb1+e\xcdSc>g\xb1+e\xcdSc>\x1c\xe8l\xc4=\xddc>\xb3z\xea\x05]\xcab>\x1c\xe8l\xc4=\xddc>g\xb1+e\xcdSc>\xd1\x1e\xae#\xaefd>\xd1\x1e\xae#\xaefd>\xd1\x1e\xae#\xaefd>\xd1\x1e\xae#\xaefd>\x85U\xef\x82\x1e\xf0d>\x85U\xef\x82\x1e\xf0d>\xb3z\xea\x05]\xcab>\xd1\x1e\xae#\xaefd>\xd1\x1e\xae#\xaefd>\x1c\xe8l\xc4=\xddc>\x1c\xe8l\xc4=\xddc>g\xb1+e\xcdSc>\xd1\x1e\xae#\xaefd>g\xb1+e\xcdSc>\x1c\xe8l\xc4=\xddc>\x1c\xe8l\xc4=\xddc>\xd1\x1e\xae#\xaefd>g\xb1+e\xcdSc>g\xb1+e\xcdSc>\xb3z\xea\x05]\xcab>\xd1\x1e\xae#\xaefd>g\xb1+e\xcdSc>\x1c\xe8l\xc4=\xddc>g\xb1+e\xcdSc>\xd1\x1e\xae#\xaefd>\xb3z\xea\x05]\xcab>\xd1\x1e\xae#\xaefd>\x1c\xe8l\xc4=\xddc>g\xb1+e\xcdSc>\x1c\xe8l\xc4=\xddc>\x85U\xef\x82\x1e\xf0d>g\xb1+e\xcdSc>g\xb1+e\xcdSc>\x85U\xef\x82\x1e\xf0d>\xd1\x1e\xae#\xaefd>g\xb1+e\xcdSc>g\xb1+e\xcdSc>\x1c\xe8l\xc4=\xddc>\x1c\xe8l\xc4=\xddc>'
>>> lzma.open('myfile.xz').read()
b'B$\xf7\xffgP\x81>\x1c\xe8l\xc4=\xddc>\xd1\x1e\xae#\xaefd>\x1c\xe8l\xc4=\xddc>g\xb1+e\xcdSc>\xd1\x1e\xae#\xaefd>\xd1\x1e\xae#\xaefd>\x1c\xe8l\xc4=\xddc>\xd1\x1e\xae#\xaefd>g\xb1+e\xcdSc>\xd1\x1e\xae#\xaefd>\x1c\xe8l\xc4=\xddc>g\xb1+e\xcdSc>g\xb1+e\xcdSc>\xd1\x1e\xae#\xaefd>\xb3z\xea\x05]\xcab>\xd1\x1e\xae#\xaefd>\xd1\x1e\xae#\xaefd>\xd1\x1e\xae#\xaefd>g\xb1+e\xcdSc>\x1c\xe8l\xc4=\xddc>g\xb1+e\xcdSc>\x1c\xe8l\xc4=\xddc>\x1c\xe8l\xc4=\xddc>g\xb1+e\xcdSc>\xb3z\xea\x05]\xcab>\x1c\xe8l\xc4=\xddc>\x1c\xe8l\xc4=\xddc>g\xb1+e\xcdSc>\xb3z\xea\x05]\xcab>\xd1\x1e\xae#\xaefd>\xd1\x1e\xae#\xaefd>g\xb1+e\xcdSc>\xb3z\xea\x05]\xcab>\x85U\xef\x82\x1e\xf0d>\x1c\xe8l\xc4=\xddc>\x1c\xe8l\xc4=\xddc>\x1c\xe8l\xc4=\xddc>\xb3z\xea\x05]\xcab>\x1c\xe8l\xc4=\xddc>g\xb1+e\xcdSc>\x1c\xe8l\xc4=\xddc>\xd1\x1e\xae#\xaefd>\x85U\xef\x82\x1e\xf0d>\x85U\xef\x82\x1e\xf0d>g\xb1+e\xcdSc>g\xb1+e\xcdSc>\x1c\xe8l\xc4=\xddc>g\xb1+e\xcdSc>\xd1\x1e\xae#\xaefd>\x1c\xe8l\xc4=\xddc>\xb3z\xea\x05]\xcab>\xb3z\xea\x05]\xcab>g\xb1+e\xcdSc>g\xb1+e\xcdSc>\x1c\xe8l\xc4=\xddc>\xb3z\xea\x05]\xcab>\x1c\xe8l\xc4=\xddc>g\xb1+e\xcdSc>\xd1\x1e\xae#\xaefd>\xd1\x1e\xae#\xaefd>\xd1\x1e\xae#\xaefd>\xd1\x1e\xae#\xaefd>\x85U\xef\x82\x1e\xf0d>\x85U\xef\x82\x1e\xf0d>\xb3z\xea\x05]\xcab>\xd1\x1e\xae#\xaefd>\xd1\x1e\xae#\xaefd>\x1c\xe8l\xc4=\xddc>\x1c\xe8l\xc4=\xddc>g\xb1+e\xcdSc>\xd1\x1e\xae#\xaefd>g\xb1+e\xcdSc>\x1c\xe8l\xc4=\xddc>\x1c\xe8l\xc4=\xddc>\xd1\x1e\xae#\xaefd>g\xb1+e\xcdSc>g\xb1+e\xcdSc>\xb3z\xea\x05]\xcab>\xd1\x1e\xae#\xaefd>g\xb1+e\xcdSc>\x1c\xe8l\xc4=\xddc>g\xb1+e\xcdSc>\xd1\x1e\xae#\xaefd>\xb3z\xea\x05]\xcab>\xd1\x1e\xae#\xaefd>\x1c\xe8l\xc4=\xddc>g\xb1+e\xcdSc>\x1c\xe8l\xc4=\xddc>\x85U\xef\x82\x1e\xf0d>g\xb1+e\xcdSc>g\xb1+e\xcdSc>\x85U\xef\x82\x1e\xf0d>\xd1\x1e\xae#\xaefd>g\xb1+e\xcdSc>g\xb1+e\xcdSc>\x1c\xe8l\xc4=\xddc>\x1c\xe8l\xc4=\xddc>'

что мне нравится. Типы тоже кажутся правильными:

>>> type(data1)
<class 'numpy.ndarray'>
>>> type(data1[0])
<class 'numpy.float64'>

>>> type(data2)
<class 'numpy.ndarray'>
>>> type(data2[0])
<class 'numpy.float64'>

Я ожидаю, что содержимое массивов data1 и data2 будет одинаковым.


person Nils_M    schedule 06.10.2017    source источник


Ответы (1)


Итак, я не знаю почему решения, но оно у меня есть. Я создал файл с помощью метода tofile .

Читал сжатую версию с frombuffer.

data_xz = np.frombuffer(lzma.open('data.bin.xz', mode='rb').read())
data_bin = np.fromfile('data.bin')

и данные равны при чтении.

Я предполагаю, что где-то обработка чтения байтов с помощью np.fromfile обнаруживает разницу в методе простого чтения и в модуле lzma.

В любом случае, для хранения данных лучше использовать согласованные форматы. Для небольших наборов данных можно использовать обычный текст. Кроме того, есть модуль постоянства joblib или HDF5 для Python.

person Pierre de Buyl    schedule 09.10.2017
comment
Спасибо за решение / обходной путь. Я бы никогда не пробовал frombuffer. - person Nils_M; 13.10.2017
comment
Рад, что это сработало для вас :-) Я подумал об этом, поскольку базовыми данными были байты, но fromfile тоже должен был это сделать: - / - person Pierre de Buyl; 13.10.2017