ved*_*ran 13 python arrays numpy memory-mapped-files
我用np.save()保存了几个numpy数组,并且放在一起它们非常庞大.
是否有可能将它们全部作为内存映射文件加载,然后连接并切换所有这些文件而不将任何内容加载到内存中?
Sau*_*tro 14
使用numpy.concatenate显然将数组加载到内存中.为避免这种情况,您可以memmap在新文件中轻松创建thrid 数组,并从要连接的数组中读取值.以更有效的方式,您还可以将新数组附加到磁盘上现有的文件中.
对于任何情况,您必须为数组选择正确的顺序(行主要或列主要).
以下示例说明了如何沿轴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
Run Code Online (Sandbox Code Playgroud)
您可以定义第三个数组,读取与要连接的第一个数组相同的文件(此处a)r+(读取和追加),但是要连接后要实现的最终数组的形状,如:
c = np.memmap('a.array', dtype='float64', mode='r+', shape=(20000,1000), order='C')
c[5000:,:] = b
Run Code Online (Sandbox Code Playgroud)
连接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
Run Code Online (Sandbox Code Playgroud)
保存在磁盘上的数组实际上是扁平化的,因此如果c使用mode=r+和shape=(5000,4000)不更改数组顺序创建,1000第二行中的第一个元素a将转到第一行c.但是你可以轻松地避免这种传递order='F'(列专业)memmap:
c = np.memmap('a.array', dtype='float64', mode='r+',shape=(5000,4000), order='F')
c[:, 3000:] = b
Run Code Online (Sandbox Code Playgroud)
这里有一个带有连接结果的更新文件'a.array'.您可以重复此过程以成对的方式连接两个.
相关问题:
也许是一个替代解决方案,但我还有一个分布在多个文件中的多维数组,我只想读取这些文件。我用dask concatenation解决了这个问题。
import numpy as np
import dask.array as da
a = np.memmap('a.array', dtype='float64', mode='r', shape=( 5000,1000))
b = np.memmap('b.array', dtype='float64', mode='r', shape=(15000,1000))
c = da.concatenate([a, b], axis=0)
Run Code Online (Sandbox Code Playgroud)
这样就可以避免额外的文件句柄。然后,dask 数组可以像任何 numpy 数组一样被切片和使用,并且当需要计算结果时,可以调用compute.
请注意,有两个注意事项:
c[::2] = 0不可能,因此在这些情况下需要创造性的解决方案。store要保存结果,应使用dask方法。这个方法可以再次接受一个memmapped数组。| 归档时间: |
|
| 查看次数: |
4253 次 |
| 最近记录: |