Python: Как сохранять списки 2D numpy массивов разной длины - PullRequest
0 голосов
/ 09 июля 2020

Я пытаюсь сохранить список массивов numpy на диск, поэтому мне не нужно создавать его каждый раз, поскольку это требует времени. Список содержит примерно 230000 numpy массивов, каждый из которых numpy имеет размеры 7xlength, где длина каждого массива может варьироваться от ~ 200 до 800.

Я пробовал np.save, но получил ошибка: «не удалось передать входной массив из shape (7,158) в shape (7)». Длина первого массива в списке составляет 158, поэтому он не работает в первом элементе списка. Я также пробовал np.savez, а также сначала преобразовал список массивов в чистый массив numpy с помощью np.asarray (listname), но я получил ту же ошибку.

Как лучше всего сохранить этот список массивов на диск, чтобы я мог загружать и использовать его по запросу?

Ответы [ 2 ]

1 голос
/ 09 июля 2020

Список с массивами, различающимися по 2-му измерению:

In [118]: alist = [np.ones((2,3)), np.zeros((2,5)), np.arange(12).reshape(2,6)]                      

Ваша ошибка:

In [119]: np.array(alist, dtype=object)                                                              
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-119-357020ce4a02> in <module>
----> 1 np.array(alist, dtype=object)

ValueError: could not broadcast input array from shape (2,3) into shape (2)

Правильный способ создания массива объектов:

In [120]: arr = np.empty(3, object)                                                                  
In [121]: arr[:] = alist                                                                             
In [122]: arr                                                                                        
Out[122]: 
array([array([[1., 1., 1.],
       [1., 1., 1.]]),
       array([[0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.]]),
       array([[ 0,  1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10, 11]])], dtype=object)

save работает:

In [123]: np.save('test.npy', arr)                                                                   
In [124]: ll test.npy                                                                                
-rw-rw-r-- 1 paul 708 Jul  8 20:13 test.npy

savez работает, с почти таким же net размером файла:

In [125]: np.savez('test.npz', *arr)                                                                 
In [126]: ll test.npz                                                                                
-rw-rw-r-- 1 paul 972 Jul  8 20:13 test.npz

Почему numpy .save производит Файл размером 100 МБ для sys.getsizeof 0,33 МБ данных? - это пример, где массивы различаются по первому измерению.

Базовая c точка - это np.save записывает массив; он пытается внести список в массив. Массив из массивов разного размера выходит за пределы numpy. Об этом начинает нас предупреждать последняя версия 1.19.

0 голосов
/ 09 июля 2020

(я удалил этот ответ, увидев, что в комментарии уже упоминается использование np.savez с *yourlist, но я восстанавливаю его, чтобы предоставить пример того, как снова прочитать данные.)

import numpy as np

list1 = [np.zeros((3,3)), np.arange(5)]

np.savez("myfile.npz", *list1)

data = np.load("myfile.npz")

list2 = [data[k] for k in data]

print(list2)

дает:

[array([[ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.]]), array([0, 1, 2, 3, 4])]

Несмотря на несколько словарный синтаксис для извлечения list2 из data, data.values() не поддерживается, хотя data.items() действителен, поэтому вы также можете сделать:

list2 = [v for k, v in data.items()]

Из экспериментов выяснилось, что если вы опустите суффикс .npz в np.savez, он будет добавлен автоматически, но если вы опустите суффикс на np.load, то файл не будет найден.

...