【问题标题】:Loading every nth element with numpy.fromfile [duplicate]使用 numpy.fromfile 加载每个第 n 个元素 [重复]
【发布时间】:2017-07-14 11:17:57
【问题描述】:

我想使用 np.fromfile 从二进制文件创建一个 numpy 数组。该文件包含一个 3D 数组,我只关心每一帧中的某个单元格。

x = np.fromfile(file, dtype='int32', count=width*height*frames)
vals = x[5::width*height]

上面的代码理论上可以运行,但我的文件非常大,将其全部读入x 会导致内存错误。有没有办法使用fromfile 只得到vals 开始?

【问题讨论】:

  • 如果您传递的是文件,而不是第一个参数的字符串,您可以简单地使用count 关键字以可管理的块读取文件。
  • Count 可让您读取前 N 个元素,但它不会帮助您加载每个第 n 个元素。文件是串行存储。将每第 n 项读取到末尾仍然需要将文件读取到末尾。
  • @hpaulj 是的,但是在较小的块上,OP 可以只使用他们发布的代码。如果抽取的结果适合内存,我不明白为什么这不起作用。还是我在这里遗漏了什么?
  • fromfile 没有任何其他参数。如果x 太适合,那么他不能选择vals。文件上的内存映射怎么样?我不知道tofile 格式是否兼容。也许np.save/load 对会更好、更灵活。

标签: python arrays numpy slice fromfile


【解决方案1】:

这可能效率极低,但确实有效:

import numpy as np

def read_in_chunks(fn, offset, step, steps_per_chunk, dtype=np.int32):
    out = []
    fd = open(fn, 'br')
    while True:
        chunk = (np.fromfile(fd, dtype=dtype, count=steps_per_chunk*step)
                 [offset::step])
        if chunk.size==0:
            break
        out.append(chunk)
    return np.r_[tuple(out)]

x = np.arange(100000)
x.tofile('test.bin')
b = read_in_chunks('test.bin', 2, 100, 6, int)
print(b)

更新:

这是一个使用seek 跳过不需要的东西的方法。它对我有用,但完全被低估了。

def skip_load(fn, offset, step, dtype=np.float, n = 10**100):
    elsize = np.dtype(dtype).itemsize
    step *= elsize
    offset *= elsize
    fd = open(fn, 'rb') if isinstance(fn, str) else fn
    out = []
    pos = fd.tell()
    target = ((pos - offset - 1) // step + 1) * step + offset
    fd.seek(target)
    while n > 0:
        if (fd.tell() != target):
            return np.frombuffer(b"".join(out), dtype=dtype)
        out.append(fd.read(elsize))
        n -= 1
        if len(out[-1]) < elsize:
            return np.frombuffer(b"".join(out[:-1]), dtype=dtype)
        target += step
        fd.seek(target)
    return np.frombuffer(b"".join(out), dtype=dtype)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-16
    相关资源
    最近更新 更多