在满足条件的非常大的内存映射中获取下一个元素的索引

Getting the index of the next element in a very large memmap which satisfies a condition

我有一个内存映射到一个非常大的 (10-100 GB) 文件,其中包含电流和电压数据。从给定的起始索引,我想找到电压满足给定条件的下一个点的索引。

在列表相对较小的情况下,我可以像这样使用迭代器来做到这一点:

filename = '[redacted]'
columntypes = np.dtype([('current', '>f8'), ('voltage', '>f8')])
data = np.memmap(filename, dtype=columntypes)
current = data['current']
voltage = data['voltage']

condition = (i for i,v in enumerate(voltage) if voltage > 0.1)
print next(condition)

但是因为我的memmap 太大了,所以无法构建迭代器。有没有办法以 pythonic 方式执行此操作而无需将数据实际加载到内存中?我总是可以采用丑陋的方法读取数据块并循环遍历它,直到找到我需要的索引,但这似乎不够优雅。

如果文件具有换行符形式的格式(如 space/new 行分隔 .csv),您可以逐行阅读和处理:

with open("foo.bar") as f:
    for line in f:
        do_something(line)

分块处理文件不一定非得是丑陋的:

with open("foo.bar") as f:
    for chunk in iter(lambda: f.read(128), ""):
        do_something(chunk)

在你的情况下,如果你知道每个输入(当前电压对)的大小,你可以将块作为原始字节加载,而不是对原始数据执行一些条件。

sizeDataPoint = 128

index = 0

lastIndex = None

with open("foo.bar") as f:
    for chunk in iter(lambda: f.read(sizeDataPoint), ""):
        if(check_conditions(chunk)):
            lastIndex = index
        index += 1

如果需要内存映射,我对 numpy 的 memmap 不是 100% 确定,但我记得使用一个名为 mmap 的 Python 库(很久以前用过)来处理非常大的文件.如果我没记错的话,它是通过一个名为 "paging".

的 OS 过程来实现的

这种尝试的效果将取决于您的 OS 是否支持它,以及它在遍历文件时处理垃圾回收的能力如何,但我认为理论上有可能超过 Python 使用 mmap 的内存限制。

编辑:此外,除非您使用 64 位 OS,否则 mmap 大文件将无法工作,因为它使用相同的地址 space.

将文件映射到内存