Python Numpy nditer用于节省内存?

Python Numpy nditer用于节省内存?,python,arrays,numpy,iteration,Python,Arrays,Numpy,Iteration,当我用nditer迭代一个数组时,我迷路了 背景 我试图计算三维阵列中每个点的3x3对称矩阵的特征值。 我的数据是一个形状为[6,x,y,z]的4D数组,其中6个值是~500x500x500立方体32上x,y,z点的矩阵值。 我首先使用了numpy的eigvalsh,但它针对大型矩阵进行了优化,而我可以对3x3对称矩阵进行分析简化 然后,我实现了这两个函数,都是一个函数,它接受单个矩阵并计算特征值(然后使用嵌套for循环进行天真的迭代),然后使用numpy进行矢量化 问题是,现在在我的矢量化中,

当我用nditer迭代一个数组时,我迷路了

背景

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

然后,我实现了这两个函数,都是一个函数,它接受单个矩阵并计算特征值(然后使用嵌套for循环进行天真的迭代),然后使用numpy进行矢量化

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

我试过使用numexpr等,它的使用量仍然在10G左右

我想做的事

我想迭代(使用numpy的nditer)我的数组,这样对于每个矩阵,我计算我的特征值。这将消除分配巨大中间数组的需要,因为我们一次只计算10个浮点数。 基本上,尝试将嵌套的
替换为
循环,使其成为一个迭代器

我在找这样的东西:

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
。迭代除第一个轴以外的所有轴的一种更简单的方法是,将其重塑为
[6500**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...

一个潜在重要的事情是,如果<代码> Simults/Corp >是C顺序(行主要)而不是FORTRAN顺序(列主要),那么在第一维度上迭代可能比迭代最后3个维度快得多,因为这样,您将访问相邻的内存地址块。因此,您可能需要考虑切换到FORTRAN命令。


我不希望从这两种方法中获得巨大的性能提升,因为在一天结束时,您仍然使用Python进行所有的循环,并且只在标量上操作,而不是利用矢量化。

只是澄清一下,我假设
symMatrix
对应于
[6,nx,ny,nz]
数组?在你的例子中,
a,b,c,
eigenOut
的形状是什么?你是对的,是同一个数组。我试着把每一项都作为浮动,但我会满足于其他项目。整个nditer练习旨在减少内存占用,同时比嵌套循环和
eigenOut
a、b、c
等形状快一点。eigenOut必须是一个[3、x、y、z]数组和一个b、c。。。视情况而定:我喜欢浮点数,但任何小数组都可以:)我还是不太明白你到底在做什么特征值分解。当
symMatrix
的第一维度是6而不是9时,如何为x、y、z中的每个点获得3x3子矩阵?感谢您的帮助!虽然这不是生产级解决方案,但我感谢您提供的解决方案。不过,我可能会求助于Cython优化,真可悲!