Что означает «[()]» при вызове массива numpy? - PullRequest
1 голос
/ 26 марта 2020

Я только что натолкнулся на этот фрагмент кода:

x = np.load(lc_path, allow_pickle=True)[()]

И я никогда не видел этот шаблон раньше: [()]. Что он делает и почему это синтаксически правильно?


a = np.load(lc_path, allow_pickle=True)
>>> array({'train_ppls': [1158.359413193576, 400.54333992093854, ...],
 'val_ppls': [493.0056070137404, 326.53203520368623, ...],
 'train_losses': [340.40905952453613, 675.6475067138672, ...],
 'val_losses': [217.46258735656738, 438.86770486831665, ...],
 'times': [19.488852977752686, 20.147733449935913, ...]}, dtype=object)

Так что я думаю, a - это dict, по какой-то причине завернутый в массив человеком, который его сохранил

Ответы [ 2 ]

2 голосов
/ 26 марта 2020

Это способ (единственный способ) индексирования массива 0d:

In [475]: x=np.array(21)                                                                       
In [476]: x                                                                                    
Out[476]: array(21)
In [477]: x.shape                                                                              
Out[477]: ()
In [478]: x[()]                                                                                
Out[478]: 21

В действительности он вытягивает элемент из массива. item() - это другой способ:

In [479]: x.item()                                                                             
Out[479]: 21
In [480]: x.ndim                                                                               
Out[480]: 0

В

x = np.load(lc_path, allow_pickle=True)[()]

скорее всего np.save был задан не массив; и обернут в массив dtype объекта 0d, чтобы сохранить его. Это способ восстановления этого объекта.

In [481]: np.save('test.npy', {'a':1})                                                         
In [482]: x = np.load('test.npy', allow_pickle=True)                                           
In [483]: x                                                                                    
Out[483]: array({'a': 1}, dtype=object)
In [484]: x.ndim                                                                               
Out[484]: 0
In [485]: x[()]                                                                                
Out[485]: {'a': 1}

В общем, когда мы индексируем nd-массив, например, x[1,2], мы действительно делаем x[(1,2)], то есть, используя кортеж, соответствующий числу размеров. Если x равен 0d, единственный работающий кортеж - пустой, ().

1 голос
/ 26 марта 2020

Это индексирование массива с кортежем из 0 индексов. Для большинства массивов это просто создает представление всего массива, но для 0-мерного массива он извлекает отдельный элемент массива в виде скаляра.

В этом случае похоже, что кто-то сделал странный выбор выгрузить не-NumPy объект в массив с numpy.save, в результате NumPy сохранит 0-мерный массив object dtype, оборачивающий исходный объект. Использование allow_pickle=True и индекса пустого кортежа извлекает объект из массива 0.

Вероятно, они должны были выбрать что-то отличное от numpy.save, чтобы сохранить этот объект.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...