Python 为什么numpy.save为sys.getsizeof 0.33MB数据生成100MB文件?

Python 为什么numpy.save为sys.getsizeof 0.33MB数据生成100MB文件?,python,numpy,Python,Numpy,我有一个numpy数组arr(由多个长度不匹配的嵌套列表生成),显然只需要 sys.getsizeof(arr)/(1000*1000) 0.33848 内存中有MB的空间。但是,当我尝试使用将此数据保存到磁盘时 myf=open('.\\test.npy', 'wb') np.save(myf, arr) myf.close() 生成的文件test.npy的大小超过了100MB 为什么呢?我在测量python内存中的实际数据大小时是否犯了一些错误? 或者,如果没有,是否有更有效地保存数据的

我有一个numpy数组
arr
(由多个长度不匹配的嵌套列表生成),显然只需要

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

内存中有MB的空间。但是,当我尝试使用将此数据保存到磁盘时

myf=open('.\\test.npy', 'wb')
np.save(myf, arr)
myf.close()
生成的文件
test.npy
的大小超过了100MB

为什么呢?我在测量python内存中的实际数据大小时是否犯了一些错误? 或者,如果没有,是否有更有效地保存数据的方法只占用硬盘上接近0.33848MB的空间

编辑:

根据评论中的要求,这里提供了
arr

arr.shape
(14101,6)

数据类型('O')

四,

338424


即使数据类型声明为
dtype('O')
,数组也只包含数值(整数和浮点数)。对象规范可能是由于嵌套列表的维度不匹配而产生的?

numpy.save
使用
pickle
存储具有“object”数据类型的数组。从:

如果数据类型包含Python对象(即dtype.hasobject为True),则数据是数组的Pythonpickle


pickle python对象的大小与其在内存中的大小不同,因此存在差异。

numpy.save
使用
pickle
存储具有“object”数据类型的数组。从:

如果数据类型包含Python对象(即dtype.hasobject为True),则数据是数组的Pythonpickle


pickle python对象的大小与其在内存中的大小不同,因此存在差异。

制作一个由多个数组组成的数组:

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

我怀疑它是可压缩的,因为最大的数组都是0。对于相同大小的随机值数组,压缩仅为454909。

制作一个由多个数组组成的数组:

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

我怀疑它是可压缩的,因为最大的数组都是0。对于相同大小的随机值数组,压缩仅为454909。

请告诉我们有关
arr
,特别是其
形状和
dtype
,而不是使用
getsizeof
。这就是我们/你需要知道的全部。但我希望
np.save
匹配,前提是
dtype
是数字或字符
arr.itemsize
arr.nbytes
也是有用的信息。我猜数据类型是“object”,因为它是从不同长度的列表创建的。OP可以确认数组的数据类型吗?如果嵌套对象本身就是数组,那么它们的
n字节
加上主字节的总和应该大致与
save
匹配。列表的内存使用更难计算,它们的pickle大小也更难计算。这可能需要一个新问题,但有几个选项(取决于嵌套级别)。如果只是一个级别(不同长度的列表),可以使用
numpy.savez
将多个数组保存到同一个文件中,也可以使用无意义的值填充它们,或者将它们串联起来并分别存储长度。如果数据是高度嵌套的,那么npy格式就不是专门为它设计的。其他选项可能是JSON,也可能是HDF5?如果您使用
MB
,请使用国际认可的缩写
MB
表示兆字节。它看起来像毫位。请告诉我们有关
arr
,特别是它的
形状和
dtype
,而不是使用
getsizeof
。这就是我们/你需要知道的全部。但我希望
np.save
匹配,前提是
dtype
是数字或字符
arr.itemsize
arr.nbytes
也是有用的信息。我猜数据类型是“object”,因为它是从不同长度的列表创建的。OP可以确认数组的数据类型吗?如果嵌套对象本身就是数组,那么它们的
n字节
加上主字节的总和应该大致与
save
匹配。列表的内存使用更难计算,它们的pickle大小也更难计算。这可能需要一个新问题,但有几个选项(取决于嵌套级别)。如果只是一个级别(不同长度的列表),可以使用
numpy.savez
将多个数组保存到同一个文件中,也可以使用无意义的值填充它们,或者将它们串联起来并分别存储长度。如果数据是高度嵌套的,那么npy格式就不是专门为它设计的。其他选项可能是JSON,也可能是HDF5?如果您使用的是
MB
,请使用国际认可的缩写
MB
表示兆字节。我明白了。有没有办法有效地将不匹配维度的嵌套列表(仅限数值)保存到二进制文件中?我明白了。有没有办法有效地将不匹配维度的嵌套列表(仅限数值)保存到二进制文件中?