Преобразование байтового массива обратно в массив numpy
Описание проблемы
Я столкнулся с проблемой при попытке восстановить массив numpy из массива байтов. Я использую функцию .tobytes()
для преобразования numpy массива в байты. Вот пример кода:
k = i.tobytes()
Однако, когда я пытаюсь декодировать его обратно в массив numpy, используя следующий код:
np.frombuffer(k) == i
Я получаю результат False
, что означает, что восстановленный массив не соответствует исходному. Чтобы прояснить, массив i
имеет форму (28, 28). Также я пробовал использовать тип данных uint8
, но это не решило проблему.
Как правильно восстановить массив numpy из массива байтов? Спасибо за вашу помощь!
2 ответ(ов)
Хотя вы можете использовать метод tobytes()
, это не является идеальным решением, так как он не хранит информацию о форме массива numpy.
В ситуациях, когда вам нужно отправить массив в другой процесс, не имея информации о его форме, вам придется передавать информацию о форме явно.
Более элегантное решение состоит в том, чтобы сохранить массив в буфер BytesIO, используя np.save
, и восстановить его с помощью np.load
. При этом вам не нужно специально хранить информацию о форме где-либо, и вы легко сможете восстановить массив numpy из байтового значения.
Пример:
>>> import numpy as np
>>> from io import BytesIO
>>> x = np.arange(28*28).reshape(28, 28)
>>> x.shape
(28, 28)
# сохраняем в буфер BytesIO
>>> np_bytes = BytesIO()
>>> np.save(np_bytes, x, allow_pickle=True)
# получаем байтовое значение
>>> np_bytes = np_bytes.getvalue()
>>> type(np_bytes)
<class 'bytes'>
# загружаем из байтов в массив numpy
>>> load_bytes = BytesIO(np_bytes)
>>> loaded_np = np.load(load_bytes, allow_pickle=True)
# форма сохранена
>>> loaded_np.shape
(28, 28)
# оба массива равны, не указывая форму
>>> np.array_equal(x, loaded_np)
True
Таким образом, использование np.save
и np.load
упрощает процесс передачи массива, исключая необходимость в манипуляциях с формой.
Если вам просто нужен бинаризованный массив, не ограничиваясь методом np.tobytes
, вы можете использовать pickle.dumps
и pickle.loads
.
Вот пример:
import pickle
import numpy as np
A = np.random.randint(0, 10, [2, 2])
A_bytes = pickle.dumps(A, protocol=0)
A_restore = pickle.loads(A_bytes)
# Проверяем тип байтов и восстановленный массив
np.testing.assert_array_equal(A_restore, A)
assert type(A_bytes) == bytes
Таким образом, вы сможете сохранить и восстановить массив NumPy без лишних сложностей!
Есть ли что-то быстрее, чем dict()?
Фиксация количества знаков после запятой с помощью f-строк
Как извлечь частоту, связанную с FFT значениями в Python?
Доступ к атрибутам на литералах работает для всех типов, кроме `int`; почему?
Цветовой график 2D массива в matplotlib