Python:将浮点字符串解压为复数
我对编码相当陌生,我从二进制文件中读取信号。数据定向为两个4字节浮点,组成一个复数,最多可重复1500个条目 我一直在使用for循环来提取数据并将复数附加到数组中Python:将浮点字符串解压为复数,python,arrays,struct,Python,Arrays,Struct,我对编码相当陌生,我从二进制文件中读取信号。数据定向为两个4字节浮点,组成一个复数,最多可重复1500个条目 我一直在使用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)
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通常是是的,有。您可以跳过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
,则这不起作用
>>> a = np.array([1,2,3,4])
>>> a
array([1, 2, 3, 4])
>>> a.dtype
dtype('int64')
>>> a.dtype = complex
>>> a
array([ 4.94065646e-324 +9.88131292e-324j,
1.48219694e-323 +1.97626258e-323j])
>>>
就你而言。您想要的数据类型是np.dtype('complex64')
,因为每个复数都是64位(2*4*8)
这会让你的速度大大加快。下面是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()
。因此,我创建了一个字符数组,然后更改了数据类型以获得相同的效果。谢谢@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)]
你一定要开始考虑numpy的C速度。可能是'numpy.frombuffer',并使用numpy中的一个复杂数据类型,而不是python的复杂数据类型。最里面的循环可以通过理解和itertools展开。
data = [[np.frombuffer(stream.readBytes(8*dimZ), dtype=np.dtype('complex64'))
for y in range(dimY)]
for x in range(dimX)]