免责声明:我总是把行和列弄得一团糟,所以我可能会在这个答案中失言......
一个重要的问题是删除不连续的数据块是一件非常重要的事情。例如,考虑一个更小的例子:
fp = np.memmap("bigarray.mat", dtype='float32', mode='w+', shape=(1000000,10000))
这个memmap 将有10**10 元素,每个元素4 个字节。这意味着这个结构将接近 40GB。它不适合我的笔记本电脑内存,所以可以使用它。
以下将移动所有行,有效地删除第 10 行:
for i in range(10, 999999):
fp[i, :] = fp[i+1, :]
这有效(几乎杀死了我的操作系统,但有效)。然而,以下将打破一切:
for i in range(10, 9999):
fp[:, i] = fp[:, i+1]
这是因为要更改第 11 列,您需要更改所有行。默认情况下,文件(和内存)中的布局是基于行的。这意味着您必须访问许多不同的地方才能获得所有必需的数字才能进行更新。
我的经验是,当事情开始不适合内存时,一切都会停止,我不知道它是在交换还是在做一些缓存。但是,有效的行为是:它突然停止并且不做任何事情。
当然,您可以为内存访问制定一些更好的算法,不需要在内存中保存完整的行等,但这是我通常不会期望的优化级别,因为它非常麻烦实施,将会非常慢(大量随机访问磁盘,如果你没有 SSD,你就死定了)并且不是很常见的情况。
如果您必须使用列,您可能需要在构建memmap 时更改order 参数。 Fortran 使用基于列而不是行的内存布局,因此将修复列删除示例。但是,在该数据结构中,删除一行将是中断操作。
这个order参数在numpy documentation的几个地方都有解释:
[参数:order,'C' 或 'F'] 指定 ndarray 内存布局的顺序:row-major,C-style 或 column-major,Fortran-style。这仅在形状大于 1-D 时才有效。默认顺序为“C”。
但是请考虑到,如果您执行“删除”,您将移动大量 GB。而且因为你不能在内存中这样做(它不适合),你需要有效地修改文件。这将是一个巨大的操作,而且会非常缓慢。我会说你可能需要某种额外的逻辑来执行“掩码”或类似的东西。但是在更高的级别上,而不是在 numpy 级别上(尽管它可能有一些封装了它的视图类,但我并不完全确定)。你还没有告诉你的用例,所以我只能猜测。但是...您正在处理大量数据,移动它是个坏主意 (TM)。