NumPy dtype принудительное расширение структурированного массива по типу - PullRequest
1 голос
/ 28 января 2020

Я использую специальный np.dtypes для программы, которая имеет такую ​​структуру:

POINT = np.dtype([('vertices', '<f4', 2), ('center', '<f4', 2), ('bbox', '<f4', 4)])

Мне нужно указать другое np.dtype, которое использует только последнее поле выше, например так:

MBR = np.dtype([('bbox', '<f4', 4)])

Это так, чтобы позже я мог получить доступ к этому полю обоих массивов следующим образом:

def intersection(s, t):

    sxmin, sxmax, symin, sxmax = s['bbox']
    txmin, txmax, tymin, tymax = t['bbox']

    # do stuff

Однако, когда я создаю следующий массив, он расширяется, и я не уверен, почему:

box = np.array([1, 2, 3, 4], dtype=MBR)
# expected output...
array([1., 2., 3., 4.], dtype=[('bbox', '<f4', 4)])
# actual output...
array([([1., 1., 1., 1.],), ..., ([4., 4., 4., 4.],)], dtype=[('bbox', '<f4', 4)])

Быстрый тест возвращает то, что я ожидал ...

np.empty([], dtype=MBR)
array(([nan, nan, inf, nan],), dtype=[('bbox', '<f4', 4)])

Редактировать:

Выполнение следующего возвращает ожидаемый результат :

box = np.array(([1, 2, 3, 4],), dtype=MBR)

Итак, теперь вопрос: Почему я должен обернуть его в кортеж, чтобы соответствовать dtype?

1 Ответ

1 голос
/ 28 января 2020

Короткий ответ: формат ввода с вложенными списками и кортежами должен соответствовать формату отображения:

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,))])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...