是否有可能np.concatenate内存映射文件?(Is it possible to np.co

2019-07-04 19:27发布

我救了一对夫妇numpy的阵列与np.save(),并把他们一起是相当巨大的。

是否有可能将它们全部装入内存映射文件,然后通过所有的人而没有加载干啥,到内存串联和分得一杯羹?

Answer 1:

使用numpy.concatenate阵列显然加载到内存中。 为了避免这种情况,你可以很容易地创建一个THRID 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

保存在磁盘阵列实际上变平,因此,如果你创建cmode=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

在这里,你有拼接结果的更新文件“a.array”。 可以重复这一过程中对二来连接。

相关的问题:

  • 在Python和numpy的大数据工作,没有足够的RAM,如何保存到光盘的部分结果?


Answer 2:

如果u使用order='F' ,会导致另一个问题,当u加载文件下一次将是退出得一塌糊涂,甚至通过order='F 所以我的解决办法是下面,我试验了很多,它只是正常工作。

fp = your old memmap...
shape = fp.shape
data = your ndarray...
data_shape = data.shape
concat_shape = data_shape[:-1] + (data_shape[-1] + shape[-1],)
print('cancat shape:{}'.format(concat_shape))
new_fp = np.memmap(new_file_name, dtype='float32', mode='r+', shape=concat_shape)
if len(concat_shape) == 1:
    new_fp[:shape[0]] = fp[:]
    new_fp[shape[0]:] = data[:]
if len(concat_shape) == 2:
    new_fp[:, :shape[-1]] = fp[:]
    new_fp[:, shape[-1]:] = data[:]
elif len(concat_shape) == 3:
    new_fp[:, :, :shape[-1]] = fp[:]
    new_fp[:, :, shape[-1]:] = data[:]
fp = new_fp
fp.flush()


文章来源: Is it possible to np.concatenate memory-mapped files?