Обмен байтами с использованием Numpy в Python

#python #arrays #python-3.x #numpy #byte

#python #массивы #python-3.x #numpy #байт

Вопрос:

Я пытаюсь выполнить обмен байтами с использованием NumPy в Python.

Я создал функцию, swap32() которая меняет местами байтовое представление массива, состоящего из 32-битных целых чисел. Я предоставляю объект с байтами младшего порядка (brr) в качестве входных данных в приведенном ниже коде, а затем функция меняет местами его байты, чтобы преобразовать его в байты большого порядка. Результат, который выдает мой код, показан ниже (что, кстати, неверно).

 >>> import numpy as np
>>> def swap32(x):
...   y = bytearray(x)
...   a = np.array(y, dtype=np.uint32)
...   return bytes(a.byteswap())

>>> arr = [1,2,3,4,5]
>>> brr = bytes(arr)
>>> brr
b'x01x02x03x04x05'

>>> swap32(brr)
b'x00x00x00x01x00x00x00x02x00x00x00x03x00x00x00x04x00x00x00x05'
  

Если я снова выполню byteswap brr , я получу следующий результат, который неверен, потому что swap32 (swap32 (brr)) должен вернуть исходный brr.

 >>> swap32(y)
b'x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x01x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x02x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x03x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x04x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x05'
  

Я, конечно, где-то ошибаюсь, чего я не могу понять. Нет ли какого-либо стандартного способа (или простого способа) поменять местами байты bytes объекта в Python?

Комментарии:

1. Что вы имеете в виду под «объектом с 32-битными байтами»? Ваш объект bytes bytes([1,2,3,4,5]) не является 32-битным ни в каком смысле, который я могу понять

2. @juanpa.arrivillaga Я также пробовал инициализировать массив с помощью int32. Но получил тот же результат — x00x00x00x01 .

3. @juanpa.arrivillaga Вы правы, что мой bytes объект не имеет 32 бит. Я хотел сказать, что у меня есть объект bytes, и я хочу выполнить обмен байтами, предполагая, что массив состоит из 32-битных целых чисел. Я обновляю сообщение. Мои извинения.

4. @juanpa.arrivillaga Хорошо, я попытался использовать np.uint8, и это удалило лишние нули, но результат по-прежнему не поменялся местами в байтах. « arr => [1, 2, 3, 4] swap32(байты(arr)) => b’ x01 x02x03x04′

5. Я думаю, я понимаю, что вы знаете, смотрите мой ответ

Ответ №1:

Хорошо, думаю, теперь я вас понимаю. Вы должны использовать np.frombuffer вместо np.array , потому что np.array обрабатывает его ввод как итерируемый, перебор байтов просто дает вам целые числа. Вы хотите обрабатывать байты как необработанный буфер.

Обратите внимание на разницу:

 >>> np.array(bytearray([1,2,3,4]), dtype=np.uint32)
array([1, 2, 3, 4], dtype=uint32)
>>> np.frombuffer(bytearray([1,2,3,4]), dtype=np.uint32)
array([67305985], dtype=uint32)
  

Итак, вы хотите что-то вроде:

 def swap32(x):
    return np.frombuffer(x, dtype=np.uint32).byteswap().tobytes()
  

Обратите внимание, для этого требуется, чтобы длина вашего объекта bytes была кратна размеру элемента массива, то есть в данном случае кратна 4.

В любом случае, в действии:

 >>> swap32(bytes([1,2,3,4]))
b'x04x03x02x01'
  

Комментарии:

1. Спасибо за ваш ответ. Я могу воспроизвести результаты для 32 бит. Просто вопрос, если я использую это с np.uint64 (при условии, что длина моего объекта bytes кратна 8), это сработает, верно?

2. @PriyanshuKhandelwal да. И signed / unsigned на самом деле не должны иметь значения в этом случае, на самом деле, но длина типа имеет значение.