【问题标题】:Read a binary file using Numpy fromfile and a given offset使用 Numpy fromfile 和给定的偏移量读取二进制文件
【发布时间】:2015-07-19 09:28:28
【问题描述】:

我有一个包含飞机位置记录的二进制文件。 每条记录如下:

0x00: Time, float32
0x04: X, float32 // X axis position
0x08: Y, float32 // Y axis position
0x0C: Elevation, float32
0x10: float32*4 = Quaternion (x,y,z axis and w scalar)
0x20: Distance, float32 (unused)

所以每条记录都是 32 字节长。

我想要一个 Numpy 数组。

在偏移量 1859 处有一个 unsigned int 32(4 字节),表示数组元素的数量。就我而言,是 12019。

我不关心(暂时)标题数据(偏移 1859 之前)

数组仅从偏移量 1863 (=1859+4) 开始。

我定义了自己的 Numpy dtype

dtype = np.dtype([
    ("time", np.float32),
    ("PosX", np.float32),
    ("PosY", np.float32),
    ("Alt", np.float32),
    ("Qx", np.float32),
    ("Qy", np.float32),
    ("Qz", np.float32),
    ("Qw", np.float32),
    ("dist", np.float32),
])

我正在使用fromfile读取文件:

a_bytes = np.fromfile(filename, dtype=dtype)

但我没有看到任何参数可以提供给fromfile 以传递偏移量。

【问题讨论】:

    标签: python arrays numpy binary


    【解决方案1】:

    您可以打开标准python文件打开文件,然后寻求跳过标题,然后将文件对象传递给fromfile。像这样的:

    import numpy as np
    import os
    
    dtype = np.dtype([
        ("time", np.float32),
        ("PosX", np.float32),
        ("PosY", np.float32),
        ("Alt", np.float32),
        ("Qx", np.float32),
        ("Qy", np.float32),
        ("Qz", np.float32),
        ("Qw", np.float32),
        ("dist", np.float32),
    ])
    
    f = open("myfile", "rb")
    f.seek(1863, os.SEEK_SET)
    
    data = np.fromfile(f, dtype=dtype)
    print x 
    

    【讨论】:

    • 谢谢。它解决了我的问题。我还注意到data = np.memmap(filename, dtype=dtype, mode='r', offset=offset_array, shape=N)`
    • 正确,如果它是一个大文件,那么 memmap 可能是要走的路。
    【解决方案2】:

    我遇到了类似的问题,但以上答案都没有让我满意。 我需要实现类似虚拟表之类的东西,其中包含大量二进制记录,这些记录可能占用比我在一个 numpy 数组中所能承受的更多的内存。所以我的问题是如何从/向二进制文件读取和写入一小组整数 - 将文件的子集写入 numpy 数组的子集。

    这是一个对我有用的解决方案:

    import numpy as np
    recordLen = 10 # number of int64's per record
    recordSize = recordLen * 8 # size of a record in bytes
    memArray = np.zeros(recordLen, dtype=np.int64) # a buffer for 1 record
    
    # Create a binary file and open it for write+read
    with open('BinaryFile.dat', 'w+b') as file:
        # Writing the array into the file as record recordNo:
        recordNo = 200 # the index of a target record in the file
        file.seek(recordSize * recordNo)
        bytes = memArray.tobytes()
        file.write(bytes)
    
        # Reading a record recordNo from file into the memArray
        file.seek(recordSize * recordNo)
        bytes = file.read(recordSize)
        memArray = np.frombuffer(bytes, dtype=np.int64).copy()
        # Note copy() added to make the memArray mutable
    

    【讨论】:

      【解决方案3】:

      我建议使用 numpy frombuffer:

      with open(file_path, 'rb') as file_obj:
          file_obj.seek(seek_to_position)
          data_ro = np.frombuffer(file_obj.read(total_num_bytes), dtype=your_dtype_here)
          data_rw = data_ro.copy() #without copy(), the result is read-only
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-09-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-24
        相关资源
        最近更新 更多