【问题标题】:numpy.memmap map to save filenumpy.memmap 映射保存文件
【发布时间】:2014-05-28 13:34:05
【问题描述】:

我正在尝试创建随机矩阵并使用 numpy.save 将其保存在二进制文件中

然后我尝试使用 numpy.memmap 映射这个文件,但它似乎映射错了。

如何解决?

它似乎读取了 .npy 标头,我需要从头开始 scip 一些字节。

rows=6
cols=4

def create_matrix(rows,cols):
    data = (np.random.rand(rows,cols)*100).astype('uint8') #type for image [0 255] int8?
    return data

def save_matrix(filename, data):
    np.save(filename, data)

def load_matrix(filename):
    data= np.load(filename)
    return data

def test_mult_ram():
    A= create_matrix(rows,cols)
    A[1][2]= 42
    save_matrix("A.npy", A)
    A= load_matrix("A.npy")
    print A
    B= create_matrix(cols,rows)
    save_matrix("B.npy", B)
    B= load_matrix("B.npy")
    print B




fA = np.memmap('A.npy', dtype='uint8', mode='r', shape=(rows,cols))
fB = np.memmap('B.npy', dtype='uint8', mode='r', shape=(cols,rows))
print fA
print fB

更新:

我刚刚发现np.lib.format.open_memmap函数已经存在了。

用法: a = np.lib.format.open_memmap('A.npy', dtype='uint8', mode='r+')

【问题讨论】:

    标签: python arrays python-2.7 numpy


    【解决方案1】:

    如果您的目标是将使用 np.save 保存的数组打开为 memmap,那么您可以使用 np.load 和选项 mmap_mode

    fA = np.load('A.npy', mmap_mode='r')
    fB = np.load('B.npy', mmap_mode='r')
    

    通过这种方式,您实际上受益于存储在 .npy 文件中的标头,因为它可以跟踪数组的形状和 dtype。

    【讨论】:

      【解决方案2】:

      npy format 有一个在使用np.memmap 时必须跳过的标头。它以一个 6 字节的魔术字符串 '\x93NUMPY' 开头,2 字节的版本号,然后是 2 字节的标头长度,然后是标头数据。

      因此,如果您打开文件,找到标头长度,然后您可以计算要传递给 np.memmap 的偏移量:

      def load_npy_to_memmap(filename, dtype, shape):
          # npy format is documented here
          # https://github.com/numpy/numpy/blob/master/doc/neps/npy-format.txt
          with open(filename, 'r') as f:
              # skip magic string \x93NUMPY + 2 bytes major/minor version number
              # + 2 bytes little-endian unsigned short int
              junk, header_len = struct.unpack('<8sh', f.read(10))
      
          data= np.memmap(filename, dtype=dtype, shape=shape, offset=6+2+2+header_len)
          return data
      

      import struct
      import numpy as np
      np.random.seed(1)
      rows = 6
      cols = 4
      
      def create_matrix(rows, cols):
          data = (np.random.rand(
              rows, cols) * 100).astype('uint8')  # type for image [0 255] int8?
          return data
      
      def save_matrix(filename, data):
          np.save(filename, data)
      
      def load_matrix(filename):
          data= np.load(filename)
          return data
      
      def load_npy_to_memmap(filename, dtype, shape):
          # npy format is documented here
          # https://github.com/numpy/numpy/blob/master/doc/neps/npy-format.txt
          with open(filename, 'r') as f:
              # skip magic string \x93NUMPY + 2 bytes major/minor version number
              # + 2 bytes little-endian unsigned short int
              junk, header_len = struct.unpack('<8sh', f.read(10))
      
          data= np.memmap(filename, dtype=dtype, shape=shape, offset=6+2+2+header_len)
          return data
      
      def test_mult_ram():
          A = create_matrix(rows, cols)
          A[1][2] = 42
          save_matrix("A.npy", A)
          A = load_matrix("A.npy")
          print A
          B = create_matrix(cols, rows)
          save_matrix("B.npy", B)
          B = load_matrix("B.npy")
          print B
      
          fA = load_npy_to_memmap('A.npy', dtype='uint8', shape=(rows, cols))
          fB = load_npy_to_memmap('B.npy', dtype='uint8', shape=(cols, rows))
          print fA
          print fB
          np.testing.assert_equal(A, fA)
          np.testing.assert_equal(B, fB)
      
      test_mult_ram()
      

      【讨论】:

      • 刚刚发现np.lib.format.open_memmap函数已经存在了。
      • @mrgloom:感谢您指出这一点。请张贴并接受它作为正确答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-01
      • 1970-01-01
      • 2016-02-23
      • 2010-12-09
      • 2012-02-08
      相关资源
      最近更新 更多