Python 位级读取二进制数据
我有一个二进制文件,其中的数据组织在16位整数块中,如下所示: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
- 位15:数字位1
- 位14:数字位2
- 位13到0:14位有符号整数
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]