gpt4 book ai didi

python - 用于节省内存的 Numpy nditer?

转载 作者:太空宇宙 更新时间:2023-11-04 05:48:45 32 4
gpt4 key购买 nike

在使用 nditer 遍历 ndarray 时我迷路了。

背景

我正在尝试为 3D 数组中的每个点计算 3x3 对称矩阵的特征值。我的数据是一个形状为 [6,x,y,z] 的 4D 数组,其中 6 个值是矩阵在 x、y、z 点的值,在 ~500x500x500 的 float32 立方体上。我首先使用了 numpy 的 eigvalsh,但它针对大型矩阵进行了优化,而我可以对 3x3 对称矩阵使用分析简化。

然后我实现了 wikipedia's simplification ,两者都是采用单个矩阵并计算特征值的函数(然后使用嵌套 for 循环简单地迭代),然后使用 numpy 进行矢量化。

问题是,现在在我的矢量化中,每个操作都会创建一个我的数据大小的内部数组,最终导致使用过多的 RAM 和 PC 卡住。

我尝试使用 numexpr 等,它仍然在 10G 左右使用。

我想做什么

我想遍历(使用 numpy 的 nditer)我的数组,以便为​​每个矩阵计算我的特征值。这将消除分配巨大的中间数组的需要,因为我们一次只计算 ~ 10 个 float 。基本上是尝试将嵌套的 for 循环替换为一个迭代器。

我正在寻找这样的东西:

for a,b,c,d,e,f in np.nditer([symMatrix,eigenOut]): # for each matrix in x,y,z

# computing my output for this matrix
eigenOut[...] = myLovelyEigenvalue(a,b,c,d,e,f)

到目前为止我最好的是:

for i in np.nditer([derived],[],[['readonly']],op_axes=[[1,2,3]]):

但这意味着 i 获取 4D 数组的所有值,而不是长度为 6 的元组。我似乎无法理解 nditer 文档。

我做错了什么?关于遍历“除了一个”轴之外,您有什么提示和技巧吗?

关键是要有一个 nditer,它会在迭代时胜过常规的嵌套循环(一旦这有效,我将更改函数调用、缓冲区迭代……但到目前为止,我只希望它能正常工作 ^^)

最佳答案

你真的不需要 np.nditer 来做这个。遍历除第一个轴以外的所有轴的更简单方法是将其 reshape 为 [6, 500 ** 3] 数组,将其转置为 [500 ** 3, 6],然后遍历行:

for (a, b, c, d, e, f) in (symMatrix.reshape(6, -1).T):
# do something involving a, b, c, d, e, f...

如果你真的想使用 np.nditer 那么你会做这样的事情:

for (a, b, c, d, e, f) in np.nditer(x, flags=['external_loop'], order='F'):
# do something involving a, b, c, d, e, f...

需要考虑的潜在重要事项是,如果 symMatrix 是 C 顺序(行优先)而不是 Fortran 顺序(列优先),那么在第一个维度上迭代可能比迭代最后 3 个维度,从那时起您将访问相邻的内存地址 block 。因此,您可能要考虑切换到 Fortran 顺序。

我不希望从其中任何一个中获得巨大的性能提升,因为在一天结束时,您仍然在 Python 中执行所有循环并且仅在标量上运行,而不是利用矢量化。

关于python - 用于节省内存的 Numpy nditer?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31180797/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com