#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 на самом деле не должны иметь значения в этом случае, на самом деле, но длина типа имеет значение.