我正在编写一些python + numpy + cython代码,并试图找到在数组上进行以下迭代的最优雅和有效的方法:
假设我有一个函数f(x,y),它采用形状(3,)的向量x和形状(10,)的向量y,并返回形状向量(10,)。现在我有两个数组X和Y形状sx +(3,)和sy +(10,),其中sx和sy是两个可以一起广播的形状(即sx == sy,或者轴不同,其中一个长度为1,在这种情况下将重复)。我想生成一个形状为zs +(10,)的数组Z,其中zs是带有sy的sx广播的形状。 Z中的每个10维向量等于X和Y中相应位置处的向量x和y的f(x,y)。
我查看了np.nditer,虽然它与cython一起玩得很好(参见链接页面的底部),它似乎不允许从多维数组迭代向量,而不是元素。我也看了index grids,但问题是当索引的数量等于数组的维数时,cython索引才会很快,并且存储为cython整数而不是python元组。
非常感谢任何帮助!
答案 0 :(得分:5)
您正在描述Numpy称为广义通用功能或gufunc的内容。顾名思义,它是ufuncs的扩展。您可能希望从阅读这两页开始:
第二个例子使用Cython并在gufunc上有一些材料。要完全走下gufunc之路,您需要阅读numpy C API文档中的相应部分:
我不知道在Cython中编码gufuncs的任何例子,尽管遵循上面的例子并不是很难。如果你想查看用C编码的gufunc,你可以看一下np.linalg
here的源代码,虽然这可能是一个令人生畏的经历。前段时间我厌倦了我的本地Python用户组,给出了关于用C扩展numpy的讨论,主要是关于在C中编写gufunc,该演讲的幻灯片和提供新gufunc的示例Python模块可以找到{{3 }}
答案 1 :(得分:2)
如果您想坚持使用nditer
,可以使用示例尺寸。它是纯Python,但不应该用cython
来实现(虽然它仍然有元组迭代器)。我正如shallow iteration with nditer
ndindex
中的想法
我们的想法是找到常见的广播形状sz
,并在其上构建一个multi_index
迭代器。
我使用as_strided
将X
和Y
扩展为可用视图,并将适当的向量(实际为(1,n)
数组)传递给{{1功能。
f(x,y)