Given that the width in bytes for rows in numpy array and the sum width of fields in a structure defined by dtype are the same, is there a simple way to convert such numpy array to a structured array?
For example, my_type
defines a data type with 5 bytes per data element in all fields: [('checksum','u2'), ('word', 'B', (3,))]
. Then I want to convert the numpy array [[ 1 2 3 4 5] [ 11 12 13 14 15]]
to the structured array [( 258, [ 3, 4, 5]) (2828, [13, 14, 15])]
.
My initial attemp was this:
import numpy as np
from random import randint
# generate data
array = np.array([(1,2,3,4,5),
(11,12,13,14,15)], dtype = np.uint8)
# format data
my_type = np.dtype([('checksum','u2'), ('word', 'B', (3,))])
structured_array = np.array([array], dtype=my_type)
But, as expected, because of numpy broadcasting rules, I get the following:
[[[( 1, [ 1, 1, 1]) ( 2, [ 2, 2, 2]) ( 3, [ 3, 3, 3])
( 4, [ 4, 4, 4]) ( 5, [ 5, 5, 5])]
[( 11, [ 11, 11, 11]) (12, [12, 12, 12]) (13, [13, 13, 13])
(14, [14, 14, 14]) (15, [15, 15, 15])]]]
My current not-so-elegant solution is to loop through the rows of an array and map them to the structure:
structured_array = np.zeros(array.shape[0], dtype=my_type)
for idx, row in enumerate(array):
for key, value in my_type.fields.items():
b = row[value[1]:value[1]+value[0].itemsize]
if len(structured_array[idx][key].shape):
structured_array[idx][key] = b
else:
structured_array[idx][key] = int.from_bytes(b, byteorder='big', signed=False)
So the question is whether there is a simple, one-line solution to perform this task for an arbitrary data type of a structured array, without parsing bytes of a numpy array?