Python f.read() 和 Octave fread()。 => 读取显示相同值的二进制文件

Python f.read() and Octave fread(). => Reading a binary file showing the same values

我正在读取一个二进制文件,其中包含 Octave 和 Python 中的信号样本。

问题是,我想为两个代码获得相同的值,但事实并非如此。

二进制文件基本上是一个复杂格式的信号 I,Q 记录为 16 位 Int。

所以,基于八度代码:

[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)

由于标志不同,我首先想到的是可能记录文件的计算机的字节序和我用来读取文件的计算机的字节序不同。所以我转向解包函数,因为它允许你强制字节序类型。

我无法在解包文档中找到 "int16": https://docs.python.org/2/library/struct.html

因此我选择 "i" 选项添加 "x" (填充字节)以满足 "struct" 文档中 table 的 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 中的值的正确方法是什么,以便我可以通过将 fread 与“int16”一起应用来获得与 Octave 中相同的值?

我一直在 Internet 上搜索此问题的答案,但找不到提供相同值的方法

非常感谢 最好的问候

看来你问题中的二进制数据是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 肯定会更有效率。