我想在不使用for循环的情况下立即将一个函数应用于两个ndarray的相应元素。假设我有以下两个ndarrays x
和y
以及一个函数foo
,它接收两个1d数组并计算beta
。
我想要的最终结果是计算beta00 = foo(x[0, 0],y[0])
,beta01 = foo(x[0, 1], y[1])
,beta10 = foo(x[1, 0],y[0])
,beta11 = foo(x[1, 1], y[1])
并产生预期的结果
[[beta00, beta01],
[beta10, beta11]]
我一直在研究vectorize函数和应用函数,但仍然没有解决方案。有人可以帮我吗?非常感谢提前。
import numpy as np
x = np.array([[[0, 1, 2, 3], [0, 1, 2, 3]],
[[2,3,4,5], [2,3,4,5]]])
y = np.array([[-1, 0.2, 0.9, 2.1], [-1, 0.2, 0.9, 2.1]])
def foo(x,y):
A = np.vstack([x, np.ones(x.shape)]).T
return np.linalg.lstsq(A, y)[0][0]
答案 0 :(得分:1)
所以你想要
beta[i,j] = foo(x[i,j,:], y[j,:])
foo
占用2个1d数组,并返回标量。显式:
表明我们正在使用3和2数组。
np.vectorize
无济于事,因为它的功能必须接受标量,而不是数组。并且 - 它不是速度解决方案。这也是启用广播,处理各种维度的输入的好方法。
有像apply_along(over)_axis
这样的循环包装器,但它们仍然是Python级循环。任何实际加速的关键都是重新处理foo
,因此它可以在2或3d阵列上运行,而不仅仅是1d阵列。但这可能比它的价值更大,甚至不可能。
因此,作为参考,任何替代方案必须匹配:
beta = np.zeros(x.shape[:2])
for i in range(x.shape[0]):
for j in range(x.shape[1]):
beta[i,j] = foo(x[i,j,:],y[j,:])
生成多维索引的另一种方法是:
for i,j in np.ndindex(x.shape[:2]):
beta[i,j] = foo(x[i,j,:], y[j,:])
但这不是节省时间。
查看是否可以编写foo
来接受2d y
,
foo(x[i,j,:], y[None,j,:])
最终能够做到:
beta = foo1(x, y[None,:])