我正在读取一个二进制文件,其中包含 Octave 和 Python 中的信号样本。
问题是,我想为两个代码获取相同的值,但事实并非如此。
二进制文件基本上是复杂格式 I、Q 的信号,记录为 16 位 Int。
因此,基于 Octave 代码:
[data, cnt_data] = fread(fid, 2 * secondOfData * fs, 'int16');
然后:
data = data(1:2:end) + 1i * data(2:2:end);
看起来很简单,只需将二进制数据读取为 16 位整数即可。然后创建最终的复数数组。
因此我假设在 Python 中我需要执行以下操作:
rel=int(f.read(2).encode("hex"),16)
img=int(f.read(2).encode("hex"),16)
in_clean.append(complex(rel,img))
好吧,我遇到的主要问题是实部和虚部值不同。
例如,在 Octave 中,第一个值为:-20390 - 10053i
在 Python 中(应用上面的代码),值为:(23216+48088j)
由于符号不同,我首先想到的是可能记录文件的计算机和我用来读取文件的计算机的字节序不同。所以我转向 unpack 函数,因为它允许您强制使用字节序类型。
我在解包文档中找不到“int16”: https://docs.python.org/2/library/struct.html
因此,我选择了“i”选项,添加了“x”(填充字节),以满足“struct”文档中表中 32 位的要求。
所以:
struct.unpack("i","xx"+f.read(2))[0]
结果是 (-1336248200-658802568j) 使用
struct.unpack("<i","xx"+f.read(2))[0]
提供相同的结果。
与:
struct.unpack(">i","xx"+f.read(2))[0]
值为:(2021153456+2021178328j)
与:
struct.unpack(">i",f.read(2)+"xx")[0]
值为:(1521514616-1143441288j)
与:
struct.unpack("<i",f.read(2)+"xx")[0]
值为:(2021175386+2021185723j)
我也尝试过使用 numpy 和“frombuffer”:
np.frombuffer(f.read(1).encode("hex"),dtype=np.int16)
提供:(24885+12386j)
那么,你知道我做错了什么吗?我想获得与 Octave 相同的值。
在 Python 中读取和解释值的正确方法是什么,以便我可以通过应用带有“int16”的 fread 来获得与 Octave 中相同的值?
我一直在互联网上寻找答案,但找不到提供相同值的方法
非常感谢 最好的问候
最佳答案
看起来您问题中的二进制数据是 5ab0bbd8
。使用 struct.unpack
解压带符号的 16 位整数,您使用 'h'
格式字符。从那(23216+48088j)
输出,看起来数据被编码为小端,所以我们需要使用 <
作为格式字符串中的第一项。
from struct import unpack
data = b'\x5a\xb0\xbb\xd8'
# The wrong way
rel=int(data[:2].encode("hex"),16)
img=int(data[2:].encode("hex"),16)
c = complex(rel, img)
print c
# The right way
rel, img = unpack('<hh', data)
c = complex(rel, img)
print c
输出
(23216+48088j)
(-20390-10053j)
请注意rel, img = unpack('<hh', data)
在 Python 3 上也能正常工作。
FWIW,在 Python 3 中,您还可以将 2 个字节解码为有符号整数,如下所示:
def int16_bytes_to_int(b):
n = int.from_bytes(b, 'little')
if n > 0x7fff:
n -= 0x10000
return n
Python 2 中的粗略等效项是:
def int16_bytes_to_int(b):
lo, hi = b
n = (ord(hi) << 8) + ord(lo)
if n > 0x7fff:
n -= 0x10000
return n
但是必须进行减法来处理有符号数字很烦人,并且使用 struct.unpack
效率肯定会更高。
关于Python f.read() 和 Octave fread()。 => 读取显示相同值的二进制文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45586255/