Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.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 位级读取二进制数据_Python_Python 3.x_Numpy - Fatal编程技术网

Python 位级读取二进制数据

Python 位级读取二进制数据,python,python-3.x,numpy,Python,Python 3.x,Numpy,我有一个二进制文件,其中的数据组织在16位整数块中,如下所示: 位15:数字位1 位14:数字位2 位13到0:14位有符号整数 我发现如何将数据从文件提取到3个数组的唯一方法是: data = np.fromfile("test1.bin", dtype=np.uint16) digbit1 = data >= 2**15 data = np.array([x - 2**15 if x >= 2**15 else x for x in data], dtype=np.uin

我有一个二进制文件,其中的数据组织在16位整数块中,如下所示:

  • 位15:数字位1
  • 位14:数字位2
  • 位13到0:14位有符号整数
我发现如何将数据从文件提取到3个数组的唯一方法是:

data = np.fromfile("test1.bin", dtype=np.uint16)

digbit1 = data >= 2**15

data = np.array([x - 2**15 if x >= 2**15 else x for x in data], dtype=np.uint16)

digbit2 = data >= 2**14

data = np.array([x-2**14 if x >= 2**14 else x for x in data])

data = np.array([x-2**14 if x >= 2**13 else x for x in data], dtype=np.int16)

现在我知道我可以对原始数据使用for循环,并填写3个单独的数组,但这仍然很难看。我想知道的是如何以
dtype=[('db',[('1',bit),('2',bit)],('temp',14bit signed int)]的风格更有效地实现这一点。
这样就可以像
数据['db']['1']一样轻松地访问它=1和0的数组

这里有一种比代码更有效的方法,因为Numpy以编译速度执行循环,这比使用Python循环快得多。我们可以使用位运算代替那些
if
测试

您没有提供任何示例数据,所以我编写了一些简单的Python 3代码来创建一些伪数据。我将数据以大格式保存到文件中,但如果您的数据实际存储在little-endian中,则很容易更改。我不使用
numpy.fromfile
读取数据,因为用普通Python读取文件,然后使用
numpy.fromfuffer
转换读取的字节会更快

唯一棘手的部分是处理那些14位有符号整数。我想你是在用表象

import numpy as np

# Make some fake data
bdata = []
bitlen = 14
mask = (1 << bitlen) - 1
for i in range(12):
    # Two initial bits
    a = i % 4
    # A signed number
    b = i - 6
    # Combine initial bits with the signed number,
    # using 14 bit two's complement.
    n = (a << bitlen) | (b & mask)
    # Convert to bytes, using 16 bit big-endian
    nbytes = n.to_bytes(2, 'big')
    bdata.append(nbytes)
    print('{} {:2} {:016b} {} {:>5}'.format(a, b, n, nbytes.hex(), n))
print()

# Save the data to a file
fname = 'test1.bin'
with open(fname, 'wb') as f:
    f.write(b''.join(bdata))

# And read it back in
with open(fname, 'rb') as f:
    data = np.frombuffer(f.read(), dtype='>u2')

print(data)

# Get the leading bits
digbit1 = data >> 15
print(digbit1)

# Get the second bits
digbit2 = (data >> 14) & 1
print(digbit2)

# Get the 14 bit signed integers
data = ((data & mask) << 2).astype(np.int16) >> 2
print(data)


如果您确实需要使用小尾端字节排序,只需将数据类型更改为
“听说过
pack
。我真的不明白numpy和二进制文件有什么关系。你能用一种更有用的方式表达你的评论吗?也许它与二进制文件本身没有多大关系,但对于这些内容来说,它确实很有用。至少对我来说,谢谢你的回答。这正是我想要的。根据numpy文档
fromfile
函数确实支持数据类型,在您的示例和我的数据中,它们都可以工作。也许值得一提的是,使用
frombuffer
打开
fromfile
@TheoryX在时间上大约快25%。我误读了
fromfile
文档的注释部分。我很快会调整我的答案。
0 -6 0011111111111010 3ffa 16378
1 -5 0111111111111011 7ffb 32763
2 -4 1011111111111100 bffc 49148
3 -3 1111111111111101 fffd 65533
0 -2 0011111111111110 3ffe 16382
1 -1 0111111111111111 7fff 32767
2  0 1000000000000000 8000 32768
3  1 1100000000000001 c001 49153
0  2 0000000000000010 0002     2
1  3 0100000000000011 4003 16387
2  4 1000000000000100 8004 32772
3  5 1100000000000101 c005 49157

[16378 32763 49148 65533 16382 32767 32768 49153     2 16387 32772 49157]
[0 0 1 1 0 0 1 1 0 0 1 1]
[0 1 0 1 0 1 0 1 0 1 0 1]
[-6 -5 -4 -3 -2 -1  0  1  2  3  4  5]