【发布时间】:2017-03-17 18:02:22
【问题描述】:
我有一个存储为 NumPy 内存映射的大型 (75000 x 5 x 6000) 3D 数组。如果我像这样简单地迭代第一个维度:
import numpy as np
import time
a = np.memmap(r"S:\bin\Preprocessed\mtb.dat", dtype='float32', mode='r', shape=(75000, 5, 6000))
l = []
start = time.time()
index = np.arange(75000)
np.random.shuffle(index)
for i in np.array(index):
l.append(np.array(a[i]) * 0.7)
print(time.time() - start)
>>> 0.503
迭代发生得非常快。但是,当我尝试在更大程序的上下文中迭代同一个 memmap 时,对 memmap 的单独调用将花费多达 0.1 秒,而拉取所有 75000 条记录将花费近 10 分钟。
较大的程序太长,无法在这里重现,所以我的问题是:是否有任何已知问题会导致 memmap 访问显着变慢,也许是 Python 内存中保存了大量数据?
在较大的程序中,用法如下所示:
import time
array = np.memmap(self.path, dtype='float32', mode='r', shape=self.shape)
for i, (scenario_id, area) in enumerate(self.scenario_areas):
address = scenario_matrix.lookup.get(scenario_id)
if address:
scenario_output = array[address]
output_total = scenario_output * float(area)
cumulative += output_total # Add results to cumulative total
contributions[int(scenario_id.split("cdl")[1])] = output_total[:2].sum()
del array
第二个示例需要 10 多分钟才能执行。 scenario_output = array[address] 行的计时,它只是从 memmap 中拉出记录,在 0.0 和 0.5 之间变化 - 半秒 拉出一条记录。
【问题讨论】:
-
是否需要立即将数据写回数组?
r+可能会让你慢下来.. -
我假设您的文件大约是 9GB? (8.4 GiB) 10 分钟,增加处理和写回并不太可怕(除非您使用的是 ssd)
-
已知问题是,除非所有内容都适合内存,否则您将交换/执行 io。如果您的访问在存储顺序中是非连续的,这可能会非常慢。
-
你能改变你的测试用例的内部循环来做一些像你的实际程序一样的 * 0.7 吗?此外,您可以将所有这些内容结合起来,让您的问题更具可读性,无需添加手动编辑历史记录,无论如何都会保留一个。
-
您不会在每次访问时将这些计时数据打印到控制台,是吗?
标签: python numpy numpy-memmap