Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python文件Slurp w/endian转换_Python_Struct_Numpy_Endianness_Mmap - Fatal编程技术网

Python文件Slurp w/endian转换

Python文件Slurp w/endian转换,python,struct,numpy,endianness,mmap,Python,Struct,Numpy,Endianness,Mmap,最近有人问了这个问题,被接受的答案是这样的: with open('x.txt') as x: f = x.read() 我将如何读取文件并转换数据的endian表示形式 例如,我有一个1GB的二进制文件,它只是一堆单精度浮点,打包成一个大端,我想把它转换成小端,然后转储到一个numpy数组中。下面是我为完成此任务而编写的函数,以及一些调用它的实际代码。我使用struct.unpack进行endian转换,并尝试使用mmap来加速一切 那么,我的问题是,我是否正确地将slurp与mmap和st

最近有人问了这个问题,被接受的答案是这样的:

with open('x.txt') as x: f = x.read()
我将如何读取文件并转换数据的endian表示形式

例如,我有一个1GB的二进制文件,它只是一堆单精度浮点,打包成一个大端,我想把它转换成小端,然后转储到一个numpy数组中。下面是我为完成此任务而编写的函数,以及一些调用它的实际代码。我使用
struct.unpack
进行endian转换,并尝试使用
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)
#/usr/bin/python
从结构导入解包
导入mmap
将numpy作为np导入
def mmapChannel(阵列名称、文件名、通道号、行计数、样本计数):
"""
我们需要读入asf内部文件并将其转换为numpy数组。
它存储为单行,是二进制的。行数(行)、样本数(列),
所有频道都来自.meta文本文件
此外,内部格式文件是压缩的大端,但大多数系统使用小端,所以我们需要
也要进行这种转换。
记忆映射似乎稍微提高了摄取速度
"""
#内存映射文件,大小0表示整个文件
#长度=行数*样本数*arrayName.itemsize
打印“\t内存映射…”
打开(文件名为“rb”)作为f:
map=mmap.mmap(f.fileno(),0,access=mmap.access\u READ)
map.seek(channelNo*line\u count*sample\u count*arrayName.itemsize)
对于X范围内的i(行计数*样本计数):
arrayName[0,i]=解包('>f',map.read(arrayName.itemsize))[0]
#与上面的方法相同,只是对于维护程序员来说更详细。
#对于X范围内的i(行计数*样本计数):#行
#be_float=map.read(arrayName.itemsize)#对于float32,arrayName.itemsize应为4
#le_float=unpack('>f',be_float)[0]#>对于大端,小于对于小端
#arrayName[0,i]=le_float
map.close()
返回arrayName
打印“初始化放大器HH HV和相位HH HV阵列…”
HHamp=np.one((1,行计数*样本计数),dtype='float32')
HHphase=np.one((1,行计数*样本计数),dtype='float32')
HVamp=np.one((1,行计数*样本计数),dtype='float32')
HVphase=np.one((1,行计数*样本计数),dtype='float32')
打印“摄入HH_放大器…”
HHamp=mmap通道(HHamp,'ALPSRP042301700-P1.1\u A.img',0,行计数,样本计数)
打印“摄入HH_阶段…”
HHphase=mmapChannel(HHphase,'ALPSRP042301700-P1.1_uua.img',1,测线计数,采样计数)
打印“摄入高压放大器…”
HVamp=MMAPC通道(HVamp,'ALPSRP042301700-P1.1\u A.img',2,线路计数,样本计数)
打印“摄入高压相…”
HVphase=mmapChannel(HVphase,'ALPSRP042301700-P1.1_ua.img',3,测线计数,采样计数)
打印“重塑…”
HHamp\u orig=HHamp.重塑(行计数,-1)
HHphase\u orig=HHphase.reformate(行计数,-1)
HVamp\U orig=HVamp.整形(线计数,-1)
HVphase\U orig=HVphase.REFORMATE(行计数,-1)

您可以使用。不过,我想知道您是否能够从算法的其他部分获得足够的性能。对1GB数据块的I/O和操作将需要一段时间,无论您以何种方式对其进行切片


另一件您可能会发现有帮助的事情是,一旦您用python原型化了算法,就可以切换到C。我做过一次对全世界DEM(高度)数据集的操作。一旦我离开了剧本,整个事情就变得更容易忍受了

我希望这样的事情会更快

arrayName[0] = unpack('>'+'f'*line_count*sample_count, map.read(arrayName.itemsize*line_count*sample_count))
请不要将
map
用作变量名

with open(fileName, "rb") as f:
  arrayName = numpy.fromfile(f, numpy.float32)
arrayName.byteswap(True)
在速度和简洁性方面很难击败;-)。byteswap请参见(参数
True
的意思是“就地执行”);有关fromfile,请参阅

这与little-endian机器上的情况一样(因为数据是big-endian的,所以需要byteswap)。您可以测试是否是有条件地执行byteswap,将最后一行从无条件呼叫更改为byteswap,例如:

if struct.pack('=f', 2.3) == struct.pack('<f', 2.3):
  arrayName.byteswap(True)
如果struct.pack('=f',2.3)==struct.pack('稍微修改:


这非常简单。谢谢你。奇怪的是,我在尝试如何实现这一点时看到了这些,但出于某种原因,它没有注册。根据经验,我想=)numpy.float32的本机字节顺序可能并不总是big-endian。事实上,它大部分都是小端,但如果你在PowerPC机上运行,它将是大端(如果这是一个问题,请有条件地忽略byteswap调用——让我编辑答案以添加该位)。测试sys.byteorder比使用struct.pack更简单。我想补充一下,对于任何觉得这篇文章有用的人。运行我的原始代码大约需要80秒左右。运行Alex Martelli和J F Sebastian提供的解决方案不到一秒钟。调用此函数的程序执行了很多次。因此,运行时间大大缩短。感谢您的帮助并教我一些东西=)您可能希望将其与.astype结合使用以将其转换为本机格式,例如,
arr=numpy.fromfile(filename,numpy.dtype('>f4')).astype(np.float32) @ Rokaou.No尝试在有或没有调用的情况下运行一些代码,看看会发生什么。@ JFSEBASTAN也许我已经从这个问题中推断出太远的实际问题,但是考虑Python代码:<代码> B= BytErRe[(0, 0, 0,1)];a=numpy.frombuffer(b,dtype=numpy.dtype('>i4'));c=a.astype(numpy.int32);(a.tostring(),c。
arr = numpy.fromfile(filename, numpy.dtype('>f4'))
# no byteswap is needed regardless of endianess of the machine