Оптимизация вложенного цикла в Python при разборе двоичных данных - PullRequest
1 голос
/ 06 ноября 2019

Я должен разобрать некоторый текст, который является двоичным, представлен в шестнадцатеричном формате, например hex_bytes в коде ниже. В этом примере есть 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 появляются в коде).

1 Ответ

1 голос
/ 14 ноября 2019

Я не знаю, быстрее ли это , чем вложенный цикл , но мы можем обойтись без циклов, создав соответствующую строку формата распаковки и распаковав все сразу:

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

Первый символ = строки формата необходим для предотвращения заполнения выравнивания между f и d.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...