python - 优化 CBOR 读取函数以将数据传递到 numpy
问题描述
我正在尝试将 CBOR 文件中的图像数据读入 Numpy 数组。
理想情况下,我正在寻找一种更有效的读取方式,将字节从二进制补码转换为无符号,然后将图像数据读入 numpy 数组。
我尝试了几种不同的方法来转换和读取字节,但无法显着提高速度。
最初我使用 for 循环来转换字节(下面的 1.),然后我使用带模数的 numpy(下面的 2.),然后转到选择性加法(下面的 3.)。
我的全部功能也在下面。
1) for x in data:
new_byte = x%256
2) ndarray%256
3) image[image<0] += 256
import os
from cbor2 import dumps, loads, decoder
import numpy as np
import itertools
def decode_image_bytes(image_byte_array):
"""Input: 1-D list of 16 bit two's compliment bytes
Operations: Converts the bytes to unsigned and decodes them
Output: a 1-D array of 16-bit image data"""
# Convert input to numpy array
image = np.array(image_byte_array)
# Convert two's complement bytes to unsigned
image[image<0] += 256
# Split the unsigned bytes into segments
bytes_array=np.array_split(image,(len(image)/2))
holder = list()
# Convert segements into integer values
for x in bytes_array:
holder.append(int.from_bytes(list(x), byteorder='big', signed=False))
return holder
def decode_image_metadata(image_dimensions_bytes_array):
"""Input: 1-D list of sint64 two's complement bytes
Operations: Converts bytes to unsigned and decodes them
Output: Dictionary with possible values: 'width, height, channels, Z, time'"""
# Convert input to numpy array
dimensions = np.array(image_dimensions_bytes_array)
# Covert two's complement bytes to unsigned
dimensions[dimensions<0] += 256
# Split the unsigned bytes into segements
bytes_array=np.array_split(dimensions,(len(dimensions)/8))
# Convert the segments into integer values
for x in range(0, len(bytes_array)):
bytes_array[x]=int.from_bytes(list(bytes_array[x]), byteorder='big', signed=True)
# Put the converted integer values into a dictionary
end = dict(itertools.zip_longest(['width', 'height', 'channels', 'Z', 'time'], bytes_array, fillvalue=None))
return end
现在需要 20-30 秒来转换字节并返回 Numpy 数组。如果可能的话,我想把它减半。
现在我想出了使用来消除 for 循环。有没有更好的方法?
bytes_array = np.apply_along_axis(metadata_values, 1, bytes_array)
def metadata_values(element):
return int.from_bytes(element, byteorder='big', signed=True)
解决方案
除非您是为自己的教育而这样做,否则您不应该在二进制数表示之间编写自己的转换,因为它会慢几个数量级。
这是一个将字节读入各种格式的 numpy 数组的示例:
>>> b = bytes([0,1,127,128,255,254]) #equivelant to reading bytes from a file in binary mode
>>> np.frombuffer(b, dtype=np.uint8)
array([ 0, 1, 127, 128, 255, 254], dtype=uint8) #notice the *U*int vs int
>>> np.frombuffer(b, dtype=np.int8)
array([ 0, 1, 127, -128, -1, -2], dtype=int8)
>>> #you can also specify other than 1 byte data formats as long as you have the right amount of bytes
>>> np.frombuffer(b, dtype=np.int16)
array([ 256, -32641, -257], dtype=int16)
>>> np.frombuffer(b, dtype=np.uint16)
array([ 256, 32895, 65279], dtype=uint16)
推荐阅读
- python - 如何在回写之前重命名openpyxl书
- angular - 为什么一个 Angular 8 应用程序闲置了很长时间
- ios - 滚动后第一个 tableview headerview 消失,但其他每个都保持可见
- python-3.x - 一系列的Python真值是函数中的模棱两可的错误
- c++ - 手动加载动态库意味着库中定义的类上的虚函数
- excel - 为什么 SpecialCells(xlCellTypeVisible) 的行为会根据使用它的函数而有所不同?
- spring-boot - SpringBoot:使用指定配置文件运行没有效果
- database - 使用 snapshot.getChildrenCount() 的值时出现问题
- python - 如何在python中定义这行代码以通过mypy检查
- python - Ansible Tower - aws_s3 模块 - 设置 python 解释器并安装依赖项