我有一个名为old_func
的旧函数,它将两个位置参数x
和y
作为输入。使用元组作为输入,函数的输入就是这样写的:
def old_func(position):
x, y = position
return x**2 + y**2
我现在想要一种通过值网格调用函数的快捷方法:
xx = numpy.linspace(0, 1, 100)
yy = numpy.linspace(0, 1, 100)
X, Y = numpy.meshgrid(xx, yy)
array_positions = (X,Y)
old_fun(array_positions)
意图是函数中x
上的每个操作都在X
上完成,y
相同。我尝试使用numpy.vectorize
对函数进行矢量化,但这不起作用。我不想更改接受NumPy数组的函数,因为这需要太长时间。
答案 0 :(得分:5)
您自己的代码应该(并且确实)正常工作:
def old_fun(position):
x, y = position
z = x**2 + y**2
return z
xx = numpy.linspace(0,1,100)
yy = numpy.linspace(0,1,100)
X,Y = numpy.meshgrid(xx, yy)
array_positions = (X,Y)
Z = old_fun(array_positions)
Z.shape
现在是(100, 100)
。
通常,numpy数组可以与任何标准运算符一起使用,例如+
和**
。请注意,虽然您的old_fun
将元组作为输入,并且此元组需要包含两个值,但只要此类型支持数学运算符,这两个值的类型可以是任何值。标准Python标量和numpy数组都支持这些,所以代码工作正常。
关于@ JuanManuel回答的说明:尽管它的效果非常好,apply_along_axis
特别是并不意味着矢量化,因为人们通常想要使用它,即从numpy中获得良好的表现。 apply_along_axis
将导致缓慢的Python循环,而不是像正确矢量化代码那样的快速C循环。您自己的代码使用了正确的矢量化,因此请使用它。
答案 1 :(得分:1)
以下代码可以解决问题,为您省去了创建array_positions
。
首先,使用ravel
将X
和Y
展平为形状为(10000,)
的NumPy数组。
X_flattened = X.ravel()
Y_flattened = Y.ravel()
然后,使用apply_along_axis
以这些展平数组的长度迭代地实现自定义函数。
float_array = np.apply_along_axis(old_func, 0, (X_flattened, Y_flattened))
最后,将输出数组重新整形为所需的(100, 100)
形状。
np.reshape(float_array, (100, 100))