为什么高阶函数在numpy中不流行

为什么高阶函数在numpy中不流行,numpy,numpy-ndarray,Numpy,Numpy Ndarray,例如,当您执行x*y+z 对于高阶函数,它可以表示为:on3(x,y,add,lambda(x,y,z):x*y+z),理论上可以节省大量计算。 我的问题是,为什么这样的模式在numpy中很少见?如果你说x*y+z使用numpy数组,x*y将分配一个临时数组,然后+z将分配最后一个数组。如果需要挤出每一点性能,可以避免使用如下中间临时数组: r = x * y r += z 这将只分配一个数组,假设您不想改变输入,这几乎是最优的。如果你真的想让它们变异,你可以这样做: x *= y # or

例如,当您执行
x*y+z
对于高阶函数,它可以表示为:
on3(x,y,add,lambda(x,y,z):x*y+z)
,理论上可以节省大量计算。
我的问题是,为什么这样的模式在numpy中很少见?如果你说
x*y+z
使用numpy数组,
x*y
将分配一个临时数组,然后
+z
将分配最后一个数组。如果需要挤出每一点性能,可以避免使用如下中间临时数组:

r = x * y
r += z
这将只分配一个数组,假设您不想改变输入,这几乎是最优的。如果你真的想让它们变异,你可以这样做:

x *= y # or np.mul(x, y, out=x)
x += z # or np.add(x, z, out=x)
那么你什么也不分配

如果数据不适合缓存,上述情况可能仍然不是最佳情况,因为您必须遍历
x
两次。通过编写矢量化函数,可以使用Numba解决此问题:

import numba

@numba.vectorize 
def fma(x, y, z): 
    return x * y + z
现在,当您运行
fma(x,y,z)
时,它将访问每个数组的第一个元素,对这三个元素运行
x*y+z
,检测结果的类型,分配该类型的输出数组,然后对其余元素进行计算

将所有内容放在一起,对输入进行单次传递,但不分配任何内容:

fma(x, y, z, out=x) # can also use out=y or out=z

这真的是关于
numpy
还是python
numpy
提供对象类(主要是
ndarray
)和函数。Python设置语法。Python是OOP,但并不强迫您编写自定义类。函数是第一类对象,可以作为参数传递。在封面下有很多函数传递和委托方法。解释一下你的替代表达式是如何节省计算的。如果它有助于描述标量和数组的情况。你的问题需要更多的上下文。你是在问像我们这样的终端用户吗?或者为什么python没有为此提供更多工具(wiki文章中有一个python示例)。或者为什么
numpy
没有更多这样的编译构建块呢?我的意思是,使用高阶函数,你可以表达很多东西,例如lambda(x,y,z,d):2*x*y+z+d)这仍然可以是零分配,而不需要像你提到的那样跳环,不清楚为什么这个模式不是零分配的exploited@bobzhang:它是可利用的,只要说
numba.vectorize(lambda x,y,z,d:2*x*y+z+d)
,你就完全满足了你的要求。numba看起来很有趣,但似乎不那么流行,鉴于这个用例非常普遍,你知道numpy为什么不首先提供它吗?要实现它需要大量的工作,NumPy的目标并不是提供每个人都需要的一切。