我用 np.save() 保存了几个 numpy 数组,放在一起它们非常大。
是否可以将它们全部加载为内存映射文件,然后连接并切分所有文件,而无需将任何内容加载到内存中?
最佳答案
显然使用 numpy.concatenate
将数组加载到内存中。为避免这种情况,您可以轻松地在新文件中创建第三个 memmap
数组,并从您希望连接的数组中读取值。以更有效的方式,您还可以将新数组附加到磁盘上的现有文件。
在任何情况下,您都必须为数组选择正确的顺序(行优先或列优先)。
以下示例说明如何沿轴 0 和轴 1 连接。
1) 沿 axis=0
a = np.memmap('a.array', dtype='float64', mode='w+', shape=( 5000,1000)) # 38.1MB
a[:,:] = 111
b = np.memmap('b.array', dtype='float64', mode='w+', shape=(15000,1000)) # 114 MB
b[:,:] = 222
您可以定义第三个数组读取与要连接的第一个数组相同的文件(此处为 a
),模式为 r+
(读取和追加),但使用连接后要实现的最终数组的形状,例如:
c = np.memmap('a.array', dtype='float64', mode='r+', shape=(20000,1000), order='C')
c[5000:,:] = b
沿 axis=0
连接不需要传递 order='C'
,因为这已经是默认顺序。
2) 沿 axis=1
a = np.memmap('a.array', dtype='float64', mode='w+', shape=(5000,3000)) # 114 MB
a[:,:] = 111
b = np.memmap('b.array', dtype='float64', mode='w+', shape=(5000,1000)) # 38.1MB
b[:,:] = 222
保存在磁盘上的数组实际上是扁平化的,所以如果您使用 mode=r+
和 shape=(5000,4000)
创建 c
在不改变数组顺序的情况下,a
中第二行的 1000
第一个元素将转到 c
中的第一行。但是你可以很容易地避免将 order='F'
(column-major) 传递给 memmap
:
c = np.memmap('a.array', dtype='float64', mode='r+',shape=(5000,4000), order='F')
c[:, 3000:] = b
这里有一个包含连接结果的更新文件“a.array”。您可以重复此过程以连接成对的两个。
相关问题:
关于python - 是否可以 np.concatenate 内存映射文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13780907/