Я пытаюсь сохранить список массивов различной формы в виде массива dtype=object
, используя np.save
(я знаю, что могу просто замариновать список, но мне действительно любопытно, как это сделать). Если я сделаю это:
import numpy as np
np.save('test.npy', [np.zeros((2, 2)), np.zeros((3,3))])
оно работает. Но это:
np.save('test.npy', [np.zeros((2, 2)), np.zeros((2,3))])
Выдает мне ошибку:
ValueError: could not broadcast input array from shape (2,2) into shape (2)
Я предполагаю, что np.save
сначала преобразует список в массив, поэтому я попробовал:
x=np.array([np.zeros((2, 2)), np.zeros((3,3))])
y=np.array([np.zeros((2, 2)), np.zeros((2,3))])
Что имеет тот же эффект (первый работает, второй нет. Полученный x
ведет себя так, как ожидалось:
>>> x.shape
(2,)
>>> x.dtype
dtype('O')
>>> x[0].shape
(2, 2)
>>> x[0].dtype
dtype('float64')
Я также пытался принудительно использовать dtype объекта:
np.array([np.zeros((2, 2)), np.zeros((2,3))], dtype=object)
Безуспешно. Кажется, numpy пытается передать массив с одинаковым первым измерением в новый массив и слишком поздно понимает, что их форма отличается. Как ни странно, в какой-то момент это сработало, поэтому мне действительно любопытно, в чем разница и как это сделать правильно.
РЕДАКТИРОВАТЬ: я понял, что это работало раньше: единственная разница, похоже, заключается в том, что массивы numpy в списке имеют другой тип данных. С dtype('<f8')
работает, а с dtype('float64')
нет, я даже не уверен, в чем разница.
РЕДАКТИРОВАТЬ 2: я нашел очень непитоновский способ решения моей проблемы, я добавляю его сюда, возможно, это поможет понять, что я хотел сделать:
array_list=np.array([np.zeros((2, 2)), np.zeros((2,3))])
save_array = np.empty((len(array_list),), dtype=object)
for idx, arr in enumerate(array_list):
save_array[idx] = arr
np.save('test.npy', save_array)