TL;DR:
np.apply_along_axis(sum, axis=0, np.stack(np.meshgrid(x, y, z)))
演练:
让我们看一个具体的例子,从创建三个一维数组开始:
x, y, z = [1, 2], [3, 4], [5, 6]
现在,让我们把这些变成meshgrid:
a, b, c = np.meshgrid(x, y, z)
这次我们得到了三个 3-d 数组:
>>> a
array([[[1, 1],
[2, 2]],
[[1, 1],
[2, 2]]])
这个数组对应我们的第一个参数,一半时间是1,另一半时间是2。这是我们在x 中的两个值。我们总共有八个值,因为我们最终输出的形状应该是2 x 2 x 2 = 8。
同样,我们有b 和c:
>>> b
array([[[3, 3],
[3, 3]],
[[4, 4],
[4, 4]]])
>>> c
array([[[5, 6],
[5, 6]],
[[5, 6],
[5, 6]]])
此时,您已经可以开始以各种方式组合这三个数组,因此对于简单的函数(可以分为两步的函数),您可以简单地运行 a + b + c 或 a & b & c。
在一般情况下,您可能希望定义接受三个数字并基于任意逻辑产生单个输出的函数。要应用这些功能,我们首先需要将stack 这三个数组合并为一个:
>>> np.stack([a, b, c])
array([[[[1, 1],
[2, 2]],
[[1, 1],
[2, 2]]],
[[[3, 3],
[3, 3]],
[[4, 4],
[4, 4]]],
[[[5, 6],
[5, 6]],
[[5, 6],
[5, 6]]]])
现在我们有 3 个大小为 8 的数组(实际形状是 3,2,2,2),我们想将一个函数 apply 一次 8 次变成三个数字:
>>> np.apply_along_axis(sum, axis=0, np.stack(np.meshgrid(x, y, z)))
array([[[ 9, 10],
[10, 11]],
[[10, 11],
[11, 12]]])
我们得到 8 个点,结果如预期的那样,每个点是 1 或 2 之一、3 或 4 之一和 5 或 6 之一的总和。
注意numpy 会将一维数组传递给f,而不是一系列参数,所以如果你有这样的函数:
def f(a, b, c):
return a + b - c
您将需要定义一个包装原始函数的附加函数:
def f2(vals):
return f(*vals)
# Alternatively:
f2 = lambda x: f(*x)
所以,现在我们可以将f2 应用于我们的数据:
>>> np.apply_along_axis(f2, 0, np.stack(np.meshgrid(x, y, z)))
array([[[-1, -2],
[ 0, -1]],
[[ 0, -1],
[ 1, 0]]])