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

标签 python arrays numpy iteration

在使用 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/

相关文章:

python - Pillow Image 对象和 numpy 数组之间的转换改变了维度

python - 在大型 3D Numpy 数组中查找局部最大值

python - 为什么 struct.pack 在性能上有如此高的可变性?

python - 使用自定义采样率将 Mp3 转换为 Wav

Python - 如果列名包含特定字符串,则更改该列中的值,否则值保留

java - split 方法在从文件读取时输出值在彼此之下

python - sqlalchemy 无法获取过滤器选项中 bool 字段的数据(用 is 指定)

java - 忽略 SORT METHOD 中的符号

arrays - 如何显示数组元素?

python - 如何优化一个 numpy 循环,该循环对一个数组中的值求和,该数组由另一个数组索引,其中值等于循环索引