从二进制文件

时间:2018-09-27 15:47:49

标签: python numpy binaryfiles

我有一个二进制文件,包含一个标题,然后是一个记录列表。每个记录是一个 n 个无符号整数的列表,后跟一个 n 个有符号整数的列表。每个记录的 n 不同。无符号整数是变量 x 的值,有符号整数是变量 y 的值。例如,数据可能看起来像这样

4 3 1 5 -10 50 40 30
4 5 6 30 -25 100
5 4 30 55

6 4 6 7 4 -20 30 30 -50 60

我需要读取该文件并将每个记录存储到( n ,2)numpy数组中,其中第一列包含 x 值,第二列包含 y 值。然后,我想将所有数组存储到一个容器numpy数组中。最后,我应该有类似的东西

np.array([
    np.array([[4, -10], [3, 50], [1, 40], [5, 30]]),
    np.array([[4, 30], [5, -25], [6, 100]]),
    np.array([[5, 30], [4, 55]]),
    array([], shape=(0, 2)),
    np.array([[6, -20], [4, 30], [6, 30], [7, -50], [4, 60]])
])

二进制文件大约200 MB,包含大约1000万条记录。每个记录的长度在标头数据中提供,我将其存储在lengths数组中。请注意,某些记录可能为空,长度为0。

现在,我有一个使用struct.unpack的有效解决方案,但这确实很慢(读取文​​件需要花费几分钟)。我遍历lengths数组并运行read_single_record函数。

def read_single_record(f, length, x_fmt, y_fmt):
    """x_fmt and y_fmt are tuples of
    (struct format character, size in bytes).
    """
    raw = f.read(length)
    n_vals = length // (x_fmt[1] + y_fmt[1])
    val = struct.unpack(
        f'{n_vals}' + x_fmt[0] + f'{n_vals}' + y_fmt[0], raw)
    val = np.array(val, dtype=np.int16).reshape((n_vals, 2), order='F')

    # do some more data processing
    # ...

    return val

records = np.empty(nb_records, dtype='object')
for i, length in enumerate(lengths):
    records[i] = read_single_record(f, length, x_fmt, y_fmt)

我已经看到others suggest在使用np.fromfile,但是我不太确定如何在可变长度的记录中使用它。

从我的二进制文件中读取可变长度记录的最有效方法是什么?

0 个答案:

没有答案
相关问题