免责声明:我总是在处理行和列时弄得一团糟,所以在回答中可能会有错误...
一个重要的问题是删除非连续的数据块并不是一件简单的事情。例如,考虑一个稍微小一点的例子:
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文档的几个地方都有解释:
[参数: order ,'C'或'F']指定ndarray内存布局的顺序:行主,C样式或列主,Fortran样式。仅在形状大于1-D时才会产生影响。默认顺序为'C'。
但是请注意,如果执行该“删除”,则将移动大量GB。并且因为您无法在内存中执行此操作(它不合适),所以您需要有效地修改文件。这将是一个巨大的操作,速度非常慢。我会说您可能需要一些额外的逻辑来执行“掩码”之类的操作。但是,在更高的级别上,而不是在numpy级别上(尽管也许它有一些视图类来封装它,我不完全确定)。您没有告诉您的用例,因此我只能猜测。但是...您正在处理大量数据,将其移动是不好的想法(TM)。