Python 为什么numpy.save为sys.getsizeof 0.33MB数据生成100MB文件?
我有一个numpy数组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内存中的实际数据大小时是否犯了一些错误? 或者,如果没有,是否有更有效地保存数据的
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
表示兆字节。我明白了。有没有办法有效地将不匹配维度的嵌套列表(仅限数值)保存到二进制文件中?我明白了。有没有办法有效地将不匹配维度的嵌套列表(仅限数值)保存到二进制文件中?