如何使用`np.fromfile`从二进制文件中读取连续数组?

jac*_*cob 6 python numpy

我想在Python中读取二进制文件,其确切的布局存储在二进制文件本身中.

该文件包含一系列二维数组,每个数组的行和列维度存储为其内容之前的一对整数.我想连续读取文件中包含的所有数组.

我知道这可以用f = open("myfile", "rb")和完成f.read(numberofbytes),但这非常笨拙,因为我需要将输出转换为有意义的数据结构.我想使用numpy的np.fromfile自定义dtype,但没有找到一种方法来读取文件的一部分,让它打开,然后继续阅读修改dtype.

我知道我可以使用osf.seek(numberofbytes, os.SEEK_SET)np.fromfile多次,但是这将在文件中围绕意味着很多不必要的跳跃.

简而言之,我想要MATLAB fread(或者至少像C++这样的东西ifstream read).

做这个的最好方式是什么?

ali*_*i_m 5

您可以将一个打开的文件对象传递给np.fromfile,读取第一个数组的维度,然后读取数组内容(再次使用np.fromfile),并对同一文件中的其他数组重复该过程。

例如:

import numpy as np
import os

def iter_arrays(fname, array_ndim=2, dim_dtype=np.int, array_dtype=np.double):

    with open(fname, 'rb') as f:
        fsize = os.fstat(f.fileno()).st_size

        # while we haven't yet reached the end of the file...
        while f.tell() < fsize:

            # get the dimensions for this array
            dims = np.fromfile(f, dim_dtype, array_ndim)

            # get the array contents
            yield np.fromfile(f, array_dtype, np.prod(dims)).reshape(dims)
Run Code Online (Sandbox Code Playgroud)

用法示例:

# write some random arrays to an example binary file
x = np.random.randn(100, 200)
y = np.random.randn(300, 400)

with open('/tmp/testbin', 'wb') as f:
    np.array(x.shape).tofile(f)
    x.tofile(f)
    np.array(y.shape).tofile(f)
    y.tofile(f)

# read the contents back
x1, y1 = iter_arrays('/tmp/testbin')

# check that they match the input arrays
assert np.allclose(x, x1) and np.allclose(y, y1)
Run Code Online (Sandbox Code Playgroud)

如果阵列很大,可以考虑使用np.memmapoffset=到位的参数np.fromfile,以获得阵列的内容作为存储器映射,而不是将它们载入RAM。