Python 使用numpy从使用numpy save保存的文件还原二进制数据

Python 使用numpy从使用numpy save保存的文件还原二进制数据,python,numpy,binaryfiles,Python,Numpy,Binaryfiles,我有一个巨大的3D数组(float16),它是使用numpy.save存储到磁盘的。当我加载它时,它会淹没我的内存,所以我需要分块读取它并一步一步地处理数据。但数据的读取顺序似乎与保存时不同。我准备了以下简单示例: import numpy as np myArray = np.zeros((2, 5, 3)) content = np.arange(0,10).reshape((2, 5)) myArray[:,:,0] = content myArray[:,:,1] = content*

我有一个巨大的3D数组(float16),它是使用
numpy.save
存储到磁盘的。当我加载它时,它会淹没我的内存,所以我需要分块读取它并一步一步地处理数据。但数据的读取顺序似乎与保存时不同。我准备了以下简单示例:

import numpy as np

myArray = np.zeros((2, 5, 3))
content = np.arange(0,10).reshape((2, 5))
myArray[:,:,0] = content
myArray[:,:,1] = content*10
myArray[:,:,2] = content*100

np.save("myArray.npy", myArray.astype(np.float16))
myArray
是一个3D数组,z方向有2行、5列和3个切片。注意,沿着
z
我在第一个片段中有0到9的数字,然后在第二个片段中有0到90的数字,在第三个片段中有0到900的数字。通过
np.load加载第一个切片效果很好,但是当我尝试以下操作时,顺序就搞乱了:

with open("myArray.npy", mode="rb") as fhandle:
    chunknp = np.fromfile(fhandle, count=10, dtype=np.float16)
    chunknp = np.resize(chunknp, new_shape=(2, 5, 1))

print(chunknp)
# Out: 
>> [[[2.630e+01]
  [2.133e+01]
  [1.700e+02]
  [5.960e-08]
  [7.033e-06]]

 [[2.922e-02]
  [1.380e+03]
  [9.535e+02]
  [2.908e-02]
  [8.255e-03]]]
Count=10
给出了我认为是z==0的2x5的前10个元素。将大小调整为(2,5,1)对这个问题不是必需的,但这是我需要的最终顺序。 我如何正确地提取这个

In [103]: myArray = np.zeros((2, 5, 3)) 
     ...: content = np.arange(0,10).reshape((2, 5)) 
     ...: myArray[:,:,0] = content 
     ...: myArray[:,:,1] = content*10 
     ...: myArray[:,:,2] = content*100 
     ...:                                                                                                 
In [104]: myArray                                                                                         
Out[104]: 
array([[[  0.,   0.,   0.],
        [  1.,  10., 100.],
        [  2.,  20., 200.],
        [  3.,  30., 300.],
        [  4.,  40., 400.]],

       [[  5.,  50., 500.],
        [  6.,  60., 600.],
        [  7.,  70., 700.],
        [  8.,  80., 800.],
        [  9.,  90., 900.]]])
In [105]: myArray.ravel()                                                                                 
Out[105]: 
array([  0.,   0.,   0.,   1.,  10., 100.,   2.,  20., 200.,   3.,  30.,
       300.,   4.,  40., 400.,   5.,  50., 500.,   6.,  60., 600.,   7.,
        70., 700.,   8.,  80., 800.,   9.,  90., 900.])
使用
tostring
显示相同的顺序:

In [108]: np.frombuffer(myArray.tostring(), dtype=float)                                                  
Out[108]: 
array([  0.,   0.,   0.,   1.,  10., 100.,   2.,  20., 200.,   3.,  30.,
       300.,   4.,  40., 400.,   5.,  50., 500.,   6.,  60., 600.,   7.,
        70., 700.,   8.,  80., 800.,   9.,  90., 900.])
要选择存储数据的连续切片,请在第一个维度上建立索引:

In [112]: myArray[0,:,:]                                                                                  
Out[112]: 
array([[  0.,   0.,   0.],
       [  1.,  10., 100.],
       [  2.,  20., 200.],
       [  3.,  30., 300.],
       [  4.,  40., 400.]])
在最后一次访问时索引
内容
值,但这不是它们在
myArray
databuffer中的存储方式:

In [113]: myArray[:,:,0]                                                                                  
Out[113]: 
array([[0., 1., 2., 3., 4.],
       [5., 6., 7., 8., 9.]])

save
写入初始信息缓冲区,然后写入数据的副本。我知道它会写入头,但我认为
np.fromfile
会立即读取并跳到数据?不,fromfile不区分该头。你必须跳过你自己。我如何知道它的大小?签出,即NPY文件文档。我通过np.moveaxis(myArray,2,0)重新计算了我的数组,将第三维带回到前面。这样,我可以在从文件中读取数据时轻松地进行切片。谢谢你指出这一点!