在您将其标记为重复之前,让我向您解释一下,我阅读了this page和许多其他内容,但我仍然没有找到解决问题的方法。在
这就是我遇到的问题:给定两个二维数组,我想对这两个数组应用函数F。F取两个1D数组作为输入。在
import numpy as np
a = np.arange(15).reshape([3,5])
b = np.arange(30, step=2).reshape([3,5])
# what is the 'numpy' equivalent of the following?
np.array([np.dot(x,y) for x,y in zip(a,b)])
请注意,np.dot
只是为了演示。这里真正的问题是在两组1D数组上工作的任何泛型函数F。在
np.apply_along_axis
迭代地应用函数;例如,使用上面定义的变量,它执行F(a[0], b[0])
,并将其与F(a[0], b[1])
和{F(a[0], b[0])
np.dot(a[np.arange(3)], b[np.arange(3)])
的操作,就会抛出一个值错误,说形状(3,5)和(3,5)没有对齐。我不知道怎么解决这个问题。在我试图用我能用的任何方法来解决这个问题,但是我想出的唯一可行的解决方案就是使用列表理解。但我担心使用列表理解会对性能造成损失。如果可能的话,我也希望通过numpy手术达到同样的效果。我该怎么做?在
这种类型的问题已经被打得死去活来了,但我将尝试用您的框架来说明这些问题:
快速理解
列表理解方法将}的3行。也就是说,它在2个数组上迭代,就像它们是列表一样。每次调用时,函数都会得到2个一维数组。
^{pr2}$f
应用于a
和{dot
可以接受其他形状,但目前我们假设它只适用于一对1d矢量化/从PyFunc
np.vectorize
迭代输入(使用广播-这很方便),并给出函数标量值。我将用frompyfunc
返回一个对象数据类型数组(由vectorize
使用):所以结果是(3,5)数组;顺便说一下,跨列求和得到了所需的结果
np.vectorize
不作任何速度承诺。在沿_轴应用_
我不知道你是如何使用
apply_along_axis
。只需要一个数组。在进行了大量的设置之后,它最终完成了以下操作(对于像a
这样的2d数组):对于3d和更大的,它使得在“其他”轴上的迭代更简单;对于2d,这是一种过度杀戮。无论如何,它都不能加快计算速度。它仍然是迭代。在
(}。它迭代
apply_along_axis
取arr
和{arr
,但使用*args
整体)。在索引
同
dot
是矩阵积,(3,5)与(5,3)一起产生(3,3)。它将1d作为特殊情况处理(参见文档),(3,)和(3,)生成(3,)。在迭代
对于真正通用的
f(x,y)
,压缩列表理解的唯一替代方法是这样的索引循环:速度也差不多。(可以使用
cython
将该操作移动到编译代码中,但我认为您还没有准备好深入研究)如注释中所述,如果数组是
(N,M)
,并且与M
相比,N
很小,那么这个迭代并不昂贵。也就是说,在一个大任务上执行几个循环是可以的。如果简化了大阵列内存管理,它们甚至可能更快。在最佳
理想的解决方案是使用numpy编译的函数重写泛型函数,使其与2d数组一起工作。在
在矩阵乘法的情况下,
einsum
在编译代码中实现了“乘积和”的广义形式:matmul
也概括了该产品,但最适合使用3d数组:如果您想用NumPy快速解决问题,请远离一般函数。尽管NumPy有一些隐藏python循环的功能,但是这些循环仍然存在(在函数内部),而且这些解决方案并不是很快(至少与普通的NumPy函数相比)。在
你应该做的是:在NumPy,SciPy中找到一个函数。。。这能满足你的需要。这些函数很快,但有时需要一些搜索和/或试验,直到找到匹配项。在
例如,矢量点乘就是按元素乘法的行的和:
相关问题 更多 >
编程相关推荐