Он был недавно спросил how to do a file slurp in python, и принятый ответ предложил что-то вроде:Python файла Slurp ж/Endian преобразования
with open('x.txt') as x: f = x.read()
Как бы я идти об этом, чтобы прочитать файл и преобразовать Endian представление данные?
Например, у меня есть двоичный файл 1 ГБ, который представляет собой всего лишь кучу одиночных прецизионных поплавков, упакованных как большой конечный элемент, и я хочу преобразовать его в маленький endian и dump в массив numpy. Ниже приведена функция, которую я написал для выполнения этого и некоторого реального кода, который его вызывает. Я использую struct.unpack
сделать преобразование в конец и попытался ускорить все, используя mmap
.
Мой вопрос тогда, я использую slurp правильно с mmap
и struct.unpack
? Есть ли более чистый и быстрый способ сделать это? Сейчас у меня есть работы, но я бы очень хотел узнать, как это сделать лучше.
Заранее благодарен!
#!/usr/bin/python
from struct import unpack
import mmap
import numpy as np
def mmapChannel(arrayName, fileName, channelNo, line_count, sample_count):
"""
We need to read in the asf internal file and convert it into a numpy array.
It is stored as a single row, and is binary. Thenumber of lines (rows), samples (columns),
and channels all come from the .meta text file
Also, internal format files are packed big endian, but most systems use little endian, so we need
to make that conversion as well.
Memory mapping seemed to improve the ingestion speed a bit
"""
# memory-map the file, size 0 means whole file
# length = line_count * sample_count * arrayName.itemsize
print "\tMemory Mapping..."
with open(fileName, "rb") as f:
map = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
map.seek(channelNo*line_count*sample_count*arrayName.itemsize)
for i in xrange(line_count*sample_count):
arrayName[0, i] = unpack('>f', map.read(arrayName.itemsize))[0]
# Same method as above, just more verbose for the maintenance programmer.
# for i in xrange(line_count*sample_count): #row
# be_float = map.read(arrayName.itemsize) # arrayName.itemsize should be 4 for float32
# le_float = unpack('>f', be_float)[0] # > for big endian, < for little endian
# arrayName[0, i]= le_float
map.close()
return arrayName
print "Initializing the Amp HH HV, and Phase HH HV arrays..."
HHamp = np.ones((1, line_count*sample_count), dtype='float32')
HHphase = np.ones((1, line_count*sample_count), dtype='float32')
HVamp = np.ones((1, line_count*sample_count), dtype='float32')
HVphase = np.ones((1, line_count*sample_count), dtype='float32')
print "Ingesting HH_Amp..."
HHamp = mmapChannel(HHamp, 'ALPSRP042301700-P1.1__A.img', 0, line_count, sample_count)
print "Ingesting HH_phase..."
HHphase = mmapChannel(HHphase, 'ALPSRP042301700-P1.1__A.img', 1, line_count, sample_count)
print "Ingesting HV_AMP..."
HVamp = mmapChannel(HVamp, 'ALPSRP042301700-P1.1__A.img', 2, line_count, sample_count)
print "Ingesting HV_phase..."
HVphase = mmapChannel(HVphase, 'ALPSRP042301700-P1.1__A.img', 3, line_count, sample_count)
print "Reshaping...."
HHamp_orig = HHamp.reshape(line_count, -1)
HHphase_orig = HHphase.reshape(line_count, -1)
HVamp_orig = HVamp.reshape(line_count, -1)
HVphase_orig = HVphase.reshape(line_count, -1)
Я хотел бы добавить к этому, для кого-то, кто считает этот пост полезным. Запуск исходного кода у меня заняло около 80 секунд или около того. Запуск решения, предоставленного Алексом Мартелли и Дж. Ф. Себастьяном, составляет менее секунды. Программа, вызывающая эту функцию, выполняет много раз. Таким образом, время работы значительно сократилось. Спасибо вам за помощь и за обучение чему-то =) – Foofy