Nó được gần đây đã hỏi how to do a file slurp in python, và câu trả lời chấp nhận đề nghị một cái gì đó như:Python file Slurp w/chuyển đổi endian
with open('x.txt') as x: f = x.read()
Làm thế nào tôi sẽ đi về việc này để đọc các tập tin trong và chuyển đổi các đại diện về cuối của dữ liệu? Ví dụ, tôi có một tập tin nhị phân 1GB chỉ là một bó nổi chính xác đơn đóng gói như một endian lớn và tôi muốn chuyển đổi nó thành một endian nhỏ và đổ vào một mảng numpy. Dưới đây là hàm tôi đã viết để thực hiện điều này và một số mã thực sự gọi nó. Tôi sử dụng struct.unpack
thực hiện chuyển đổi cuối cùng và cố gắng tăng tốc mọi thứ bằng cách sử dụng mmap
.
Câu hỏi của tôi là, tôi có đang sử dụng chính xác slurp với mmap
và struct.unpack
không? Có cách nào sạch hơn, nhanh hơn để thực hiện việc này không? Ngay bây giờ những gì tôi đã làm việc, nhưng tôi thực sự muốn tìm hiểu làm thế nào để làm điều này tốt hơn.
Cảm ơn trước!
#!/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)
tôi muốn thêm vào này, đối với bất kỳ ai khác tìm thấy bài này hữu ích. Chạy mã gốc tôi đã mất khoảng 80 giây hoặc lâu hơn. Chạy các giải pháp được cung cấp bởi Alex Martelli và J F Sebastian là ít hơn một giây. Chương trình gọi hàm này thực hiện quá nhiều lần. Như vậy, thời gian chạy đã giảm đáng kể. Cảm ơn cả hai vì sự giúp đỡ và để dạy tôi điều gì đó =) – Foofy