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

У меня есть numpy массив arr (созданный из нескольких вложенных списков несовпадающих длин), который, по-видимому, занимает только

sys.getsizeof(arr)/(1000*1000)

0,33848

МБ свободного места в памяти. Однако, когда я пытаюсь сохранить эти данные на диск с помощью

myf=open('.\\test.npy', 'wb')
np.save(myf, arr)
myf.close()

, полученный файл test.npy оказывается размером более 100 МБ.

Почему это так? Я ошибся с измерением фактического размера данных в памяти python? Или, если нет, есть ли способ сохранить данные более эффективно, занимая только около 0,33848 МБ места на жестком диске?

EDIT:

Как указано в комментарии, вот еще несколько свойств arr

arr.shape

(14101, 6)

arr.dtype

dtype ('O')

arr.itemsize

4

arr.nbytes

338424

, хотя dtype утверждает, что dtype('O') , массив содержит только числовые значения (целые числа и числа с плавающей запятой). Может быть, спецификация объекта возникает из-за несовпадения размеров вложенных списков?

Ответы [ 2 ]

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

Составьте массив из нескольких массивов:

In [98]: arr = np.array([np.ones(10), np.zeros((200,300)),np.arange(1000).reshape(100,10)],object)   

Общее использование памяти:

In [100]: sum([a.nbytes for a in arr]+[arr.nbytes])                                                  
Out[100]: 488104

Сохраните его и проверьте размер файла

In [103]: np.save('test.npy', arr, allow_pickle=True)                                                
In [104]: ll test.npy                                                                                
-rw-rw-r-- 1 paul 488569 Jul  8 17:46 test.npy

Это достаточно близко!

Архив npz занимает примерно такое же пространство:

In [106]: np.savez('test.npz', *arr)                                                                 
In [107]: ll test.npz                                                                                
-rw-rw-r-- 1 paul 488828 Jul  8 17:49 test.npz

Но сжатие помогает значительно:

In [108]: np.savez_compressed('test.npz', *arr)                                                      
In [109]: ll test.npz                                                                                
-rw-rw-r-- 1 paul 2643 Jul  8 17:50 test.npz

Я подозреваю, что он настолько сжимаем, потому что самый большой массив все нули. С массивами случайных значений одинакового размера сжатие только до 454909.

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

numpy.save использует pickle для хранения массивов, имеющих dtype "объект". Из документации по формату numpy :

Если dtype содержит Python объекты (т.е. dtype.hasobject имеет значение True), тогда данные будут a Python pickle массива

Размер маринованного объекта python не совпадает с его размером в памяти, отсюда расхождение.

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