Python:将浮点字符串解压为复数

2024-09-27 23:16:12 发布

您现在位置:Python中文网/ 问答频道 /正文

我对编码相当陌生,我正在从二进制文件中读取信号。数据被定向为两个4字节的浮点型,组成一个复数,这会在多达1500个ish条目中重复

我一直在使用for循环来提取数据并将复数追加到数组中

for x in range(dimX):
    for y in range(dimY):
        complexlist=[]
        #2 floats, each 4 bytes, is one complex number
        trace=stream.readBytes(8*dimZ)
        #Unpack as list of floats
        floatlist=struct.unpack("f"*2*dimZ,trace)
        for i in range(0,len(floatlist)-1,2):
            complexlist.append(complex(floatlist[i],floatlist[i+1]))        
        data[x][y]=np.array(complexlist)

如果dimX可能是数千,那么DimY通常是<;30,dimZ是<;1500

但在大文件中这是非常缓慢的

有没有办法读取整个跟踪的缓冲区并直接解包到复数数组中?在


Tags: 文件数据inltfortracerange数组
1条回答
网友
1楼 · 发布于 2024-09-27 23:16:12

是的,有。您可以跳过python复杂类型的步骤,因为在内部,numpy将n复数数组表示为2n浮点数组。在

下面是一个来自REPL的简单示例:

>>> import numpy as np
>>> a = np.array([1.,2.,3.,4.])
>>> a
array([ 1.,  2.,  3.,  4.])
>>> a.dtype
dtype('float64')
>>> a.dtype = complex
>>> a
array([ 1.+2.j,  3.+4.j])
>>> 

请注意,如果初始数组的dtype不是float,那么这就不起作用了。在

^{pr2}$

对你来说。您想要的数据类型是np.dtype('complex64'),因为每个复数都是64位(2*4*8)。在

for x in range(dimX):
    for y in range(dimY):
        #2 floats, each 4 bytes, is one complex number
        trace=stream.readBytes(8*dimZ)
        a = np.frombuffer(trace,dtype=np.dtype('complex64'))
        data[x][y] = a

那应该能让你加快速度。下面是REPL中关于numpy.frombuffer()如何工作的示例

>>> binary_string = struct.pack('2f', 1,2)
>>> binary_string
'\x00\x00\x80?\x00\x00\x00@'
>>> numpy.frombuffer(binary_string, dtype=np.dtype('complex64'))
array([ 1.+2.j], dtype=complex64)
>>> 

编辑:我不知道numpy.frombuffer()的存在。所以我创建了一个char数组,然后更改了dtype以获得相同的效果。谢谢@wim

编辑2:

至于进一步的速度优化,使用列表理解而不是显式for循环可能会提高性能。在

for x in range(dimX):
    data[x] = [np.frombuffer(stream.readBytes(8*dimZ), dtype=np.dtype('complex64')) for y in range(dimY)]

但更进一步:

data = [[np.frombuffer(stream.readBytes(8*dimZ), dtype=np.dtype('complex64'))
         for y in range(dimY)]
         for x in range(dimX)]

相关问题 更多 >

    热门问题