Python解析二进制数据时嵌套循环的优化

Python解析二进制数据时嵌套循环的优化,python,parsing,optimization,nested-loops,binary-data,Python,Parsing,Optimization,Nested Loops,Binary Data,我必须解析一些以十六进制小数表示的二进制文本,例如下面代码中的十六进制字节。在这个例子中,有32个变量和3个点,这意味着我有32个变量重复了3次。 hex_bytes包含32个变量的值,一次、二次、三次。 问题是,我需要将第一个变量转换为双精度(8字节),将所有其他变量转换为单精度(4字节) 我制作了一个数组(32列和3行),我只填充了第一列,其中包含双精度转换值,其他所有列都使用单个精度值 我有一个嵌套循环,它可以工作,但我想知道有没有比嵌套循环更快的解决方案?我尝试了一个lambda()函数

我必须解析一些以十六进制小数表示的二进制文本,例如下面代码中的十六进制字节。在这个例子中,有32个变量和3个点,这意味着我有32个变量重复了3次。 hex_bytes包含32个变量的值,一次、二次、三次。 问题是,我需要将第一个变量转换为双精度(8字节),将所有其他变量转换为单精度(4字节)

我制作了一个数组(32列和3行),我只填充了第一列,其中包含双精度转换值,其他所有列都使用单个精度值

我有一个嵌套循环,它可以工作,但我想知道有没有比嵌套循环更快的解决方案?我尝试了一个lambda()函数,也尝试了zip(),但我无法在代码中正确实现它们。我在实现8或16的增量时遇到问题

代码如下:

import binascii
from struct import *
import numpy as np

hex_bytes = b'00000000000000000000a040000000000000a0401264062c321bd3ac00000000321bd32c00d42fae0000000000d42f2e0098412d00000000009841ad00e8192e0000000000e819ae93f9810200000000004060ae00000000ce14b02c66374a2e004e4aae000000000060afac00d42f2e00e819ae00000000ce14b02c321bd32c009841ad00000015316b673c0000a040000000000000a040b0422e2adf037fb6fef1d0349fe56436eebafcb5000080b3775d0236c6c915ad000000b35c09003386ad33b44d91be34157549b4b0ffe635cbcbe9b26edcb5b64d919e3405047fb68ba1b336be7229b44d919e344f9809b6775d0236157549b4fef1c03405047fb69fe564365c090033d0ee42f1df7ceb3d0000a040000000000000a0407d23202d26aaaab520a11034029698350bf228b594338d2bfaf128355681822e36641fac680c7bae200f70b3e44ffe33534886b3cf001c35c18d1cb2ed1cf4b57150fe331ca8aab5fe0eed35b56786b37150fe33fcf237b5faf12835534886b380a010341ca8aab502969835680c7baed76617efa79df43d0000a040000000000000a040e44c2b2d2cf7eead4541acab40bbf92d5b069bae0b81982b57a4982ea8f4752e73e02caca0266baee6ee462e7be754aafe1946ae2848b9a6563776ab00070baf36c87b2b22f2fc2d2713d72e4fa0d8ae36c87b2ba03bdead57a4982efe1946ae8b8081ac22f2fc2d40bbf92da0266bae48afbc9af2d77a3e0000a040000000000000a0402369062c7bb5d3acc84c84a8c739d42cd6e42fae74f268a9131f302e9ce0412d7ace14a9cd4b41ad71f5192eb0e04b263cf619ae35d644250000c028002060aef2c265a9bd0bb02c4ca64a2e30494aaef2c265a92e7bafac131f302e3cf619aedef456a9bd0bb02cc739d42ccd4b41ad65698779f6d77a3e0600a040e02d903a0000a0404351ec315a6a873458567135c3859ab52db5d2384888be399335f3b9f38988b4cacb7035d1862cb57179d6b8a30cbe39476e88b9f6fa0f31754a3eba18d0f339754a3e3a83cc0fb119d0f3b98ac488b9754a3e3aee10f1b59335f3b9476e88b91111f13583cc0fb1c3859ab5d1862cb5'

NoPoints = 3
NoVariables = 32

Values = np.zeros((NoPoints,NoVariables))
BinaryStart = 0

for NoPt in range(NoPoints):
    for NoVar in range(NoVariables):
        if NoVar == 0:
            Values[NoPt,NoVar], = unpack('d', binascii.a2b_hex(hex_bytes[BinaryStart:BinaryStart+16]))
            BinaryStart +=16
        else:
            Values[NoPt,NoVar], = unpack('f', binascii.a2b_hex(hex_bytes[BinaryStart:BinaryStart+8]))
            BinaryStart += 8
请注意,8个二进制字符表示4个字节,16个二进制字符表示8个字节(这就是代码中出现8和16的原因)。

我不知道它是否比嵌套循环快,但我们可以通过构造适当的解包格式字符串并一次性解包来避免循环:

Values = np.array(unpack('='+('d'+str(NoVariables-1)+'f')*NoPoints, binascii.a2b_hex(hex_bytes)))\
           .reshape((NoPoints, NoVariables))

格式字符串的第一个字符
=
需要防止
f
d

之间的对齐填充。在本例中,有32个变量和3个点-不,实际上有6个点,并且只转换十六进制字节的前半部分。“这是我想要的,还是一个错误?”阿玛利显然不明白unpack()是如何工作的。伟大的速度快了两倍多。我有一个变体-如果每个变量都有两个双精度值要转换,如何更改代码?value=np.array(解包('dd')*NoVariables*NoPoints,binascii.a2b_hex(hex_bytes))\。重塑((NoPoints,NoVariables,2)…我就是这样做的。谢谢。现在你显然明白了解包()的工作原理了。;-)