首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用RAM的Python广播4D阵列

使用RAM的Python广播4D阵列
EN

Stack Overflow用户
提问于 2022-02-18 13:47:46
回答 1查看 71关注 0票数 1

我试图对4D图像阵列(包括时间序列)做简单的计算,但是与初始化的数组相比,广播占用了大量的RAM,而且我已经尝试用一些类似的问题来读取其他内存。例如Memory growth with broadcast operations in NumPy

在这里,来自"rth“的评论说:”广播不为初始数组分配额外的内存“。

“Weckesser”所接受的评论显示了提问者使用og newaxis来创建额外的分配数组的问题。

我试着做沃伦展示的东西,但是我仍然被大量的内存消耗掉,我不知道为什么。现在,我已经实现了rths块计算方法,并取得了很好的结果,但它仍然困扰着我,为什么直接的numpy计算会在RAM的使用中崩溃。

这里是我所做的事情的一个例子,

我初始化了将数据添加到其中的数组,并创建了uint16的随机原始图像,因为它来自带有12位原始图像数据的16位TIFF文件。我保留其余的float32来保存内存。最后的精度没那么重要

代码语言:javascript
复制
import numpy as np
imagearraydensity = np.ones((512, 1024, 250, 20),dtype=np.float32)
imagearrayraw = np.random.randint(4095,size=(512, 1024, 250, 20),dtype=np.uint16)

我手上有两个线性常数数组,这里只是随机数。

代码语言:javascript
复制
acons = np.random.random((512, 1024)).astype(np.float32)
bcons = np.random.random((512, 1024)).astype(np.float32)

然后计算

代码语言:javascript
复制
np.divide(np.subtract(imagearrayraw, bcons[:, :, np.newaxis, np.newaxis], dtype=np.float32),
                      acons[:, :, np.newaxis, np.newaxis],
                      imagearraydensity,  # Output array position
                      dtype=np.float32)

当计算完成时,我的实际数据代码将在我的系统上使用~ 36 GB的RAM和~27 GB的内存。

我能做些什么来减少直接广播对RAM的使用吗?还是像我已经实现的那样,基于块的方法是最好的方法?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-02-18 17:20:31

首先,两个输入数组包含2_621_440_000项,从而产生15 GiB的内存。由np.subtract生成的临时数组包含相同数量的元素,从而产生10 GiB的内存。输出数组被覆盖,因此不应该占用更多的RAM。这意味着Numpy应该已经占用了25 GiB的内存。

问题是,Numpy不知道如何从uint16数组中减去float32数组。因此,它应用了导致uint16 数组被抛给数组的semantic rules。这意味着它创建了一个新的10 GiB临时数组,从而占用了内存的~36 GiB。注意,Numpy和Python都不是为了最小化内存占用而设计的。

尽管如此,解决这一问题有几个解决办法。一种解决方案是将输入数据分割成块,以便临时数组占用更少的空间。这件事做起来很麻烦。另一个理论上的解决方案是自己转换数组,以便用imagearrayraw编写它,但是Numpy没有为astype提供一个out参数。另一种解决方案是使用Numba以便执行强制执行(这是更有效的)。

以下是基于块的解决方案:

代码语言:javascript
复制
for i in range(imagearraydensity.shape[0]):
    imagearraydensity[i,...] = imagearrayraw[i,...].astype(np.float32)
np.subtract(imagearraydensity, bcons[:, :, np.newaxis, np.newaxis], out=imagearraydensity, dtype=np.float32)
np.divide(imagearraydensity, acons[:, :, np.newaxis, np.newaxis], out=imagearraydensity, dtype=np.float32)

这个解决方案在我的机器上需要15 GiB。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71174542

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档