rob*_*ert 5 python memory arrays numpy out-of-memory
假设我有一个非常大的numpy内存映射数组:
fp = np.memmap("bigarray.mat", dtype='float32', mode='w+', shape=(5000000,5000))
Run Code Online (Sandbox Code Playgroud)
现在经过一些操作等,我想删除第10列:
fp = np.delete(fp,10,1)
Run Code Online (Sandbox Code Playgroud)
这会导致内存不足错误,因为(??)返回的数组是内存数组.我想要的是纯内存映射删除操作.
在完全内存映射模式下删除列的最有效方法是什么?
免责声明:我总是把行和列弄乱,所以我可能会在这个答案中说漏嘴......
\n\n一个重要的问题是删除不连续的数据块是一件非常重要的事情。例如,考虑一个更小的例子:
\n\nfp = np.memmap("bigarray.mat", dtype=\'float32\', mode=\'w+\', shape=(1000000,10000))\n
Run Code Online (Sandbox Code Playgroud)\n\n这memmap
将有10**10
元素,每个元素 4 个字节。这意味着该结构的大小将接近 40GB。它不适合我的笔记本电脑内存,因此可以使用它。
以下命令将移动所有行,从而有效删除第 10 行:
\n\nfor i in range(10, 999999):\n fp[i, :] = fp[i+1, :]\n
Run Code Online (Sandbox Code Playgroud)\n\n这有效(几乎杀死了我的操作系统,但有效)。然而,以下内容将破坏一切:
\n\nfor i in range(10, 9999):\n fp[:, i] = fp[:, i+1]\n
Run Code Online (Sandbox Code Playgroud)\n\n这是因为为了更改第 11 列,您需要更改所有行。默认情况下,文件(和内存)中的布局是基于行的。这意味着您必须访问许多不同的地方才能获取所有所需的号码才能进行更新。
\n\n我尝试的经验是,当事情开始不适合内存时,一切都会变得停滞,我不知道它是在交换还是在做一些缓存。但是,有效的行为是:它突然停止并且不执行任何操作。
\n\n当然,您可以为内存访问制定一些更好的算法,该算法不需要在内存中保存完整的行等,但这是我通常不会期望的优化级别,因为实现起来非常麻烦,会非常慢(对磁盘进行大量随机访问,如果你没有 SSD,那么你就死定了)并且不是很常见的情况。
\n\n如果您必须使用列,您可能需要order
在构建memmap
. Fortran 使用基于列而不是行的内存布局,因此这将修复列删除示例。然而,在该数据结构中,删除一行将是破坏操作。
这个参数在numpy 文档order
的几个地方都有解释:
\n\n\n[参数:
\norder
,\'C\'
或\'F\'
] 指定 ndarray 内存布局的顺序:行优先、C 风格或列优先、Fortran 风格。仅当形状大于一维时这才有效。默认顺序为 \xe2\x80\x98C\xe2\x80\x99。
但请考虑到,如果执行“删除”,您将移动大量 GB。由于您无法在内存中执行此操作(它不适合),因此您将需要有效地修改该文件。这将是一个巨大的操作,而且速度非常慢。我想说,您可能需要某种额外的逻辑来执行“掩码”或类似的操作。但在更高的层面上,而不是在 numpy 层面上(尽管它可能有一些封装了它的视图类,但我不完全确定)。你还没有告诉你的用例,所以我只能猜测。但是......您正在处理大量数据,移动它们是坏主意(TM)。
\n 归档时间: |
|
查看次数: |
541 次 |
最近记录: |