1

我有一个包含电流和电压数据的非常大(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 的方式执行此操作,而无需实际将数据加载到内存中?我总是可以采取丑陋的方法来读取数据块并循环遍历它,直到找到我需要的索引,但这似乎不优雅。

4

1 回答 1

1

如果文件具有换行符形式的格式(如空格/新行分隔的 .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

如果需要内存映射,我不能 100% 确定 numpy 的 memmap,但我记得使用一个名为 mmap 的 Python 库(很久以前使用它)来处理非常大的文件。如果我没记错的话,它是通过一个称为“分页”的操作系统进程来实现的。

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

编辑:此外,除非您使用 64 位操作系统,否则 mmap 大文件将不起作用,因为它使用相同的地址空间将文件映射到内存。

于 2018-05-08T21:07:11.033 回答