Короткий ответ: формат ввода с вложенными списками и кортежами должен соответствовать формату отображения:
In [59]: MBR = np.dtype([('bbox', '<f4', 4)])
In [60]: arr = np.zeros(3, dtype=MBR)
In [61]: arr
Out[61]:
array([([0., 0., 0., 0.],), ([0., 0., 0., 0.],), ([0., 0., 0., 0.],)],
dtype=[('bbox', '<f4', (4,))])
In [62]: arr[0]
Out[62]: ([0., 0., 0., 0.],)
In [63]: arr[0]=[1,2,3,4]
In [64]: arr[1]=[10,11,12,13]
In [65]: arr
Out[65]:
array([([ 1., 2., 3., 4.],), ([10., 11., 12., 13.],),
([ 0., 0., 0., 0.],)], dtype=[('bbox', '<f4', (4,))])
In [66]: np.array([([1,2,3,4],)],MBR)
Out[66]: array([([1., 2., 3., 4.],)], dtype=[('bbox', '<f4', (4,))])
Таким образом, для типичного составного dtype мы говорим, что входные данные должны быть списком кортежи, один кортеж на «запись» массива. Внутри кортежа по одному элементу на поле.
У вас есть дополнительное усложнение измерения размера (4,) внутри поля.
Обратите внимание, что форма поля, извлеченная из массива , объединяет внешнюю форму массива с внутренней формой поля:
In [67]: arr['bbox']
Out[67]:
array([[ 1., 2., 3., 4.],
[10., 11., 12., 13.],
[ 0., 0., 0., 0.]], dtype=float32)
Зачастую проще присвоить значения структурированному массиву по полю, а не по записи:
In [68]: arr['bbox']=np.arange(12).reshape(3,4)
In [69]: arr
Out[69]:
array([([ 0., 1., 2., 3.],), ([ 4., 5., 6., 7.],),
([ 8., 9., 10., 11.],)], dtype=[('bbox', '<f4', (4,))])