在numpy中优雅地生成结果数组

在numpy中优雅地生成结果数组,numpy,Numpy,我有我的X和Y numpy阵列: X = np.array([0,1,2,3]) Y = np.array([0,1,2,3]) 以及将x、y值映射到Z点的函数: def z(x,y): return x+y 我希望生成3D绘图所需的显而易见的东西:对应Z值的二维numpy数组。我认为应该是这样的: Z = np.array([[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5],

我有我的X和Y numpy阵列:

X = np.array([0,1,2,3])
Y = np.array([0,1,2,3])
以及将x、y值映射到Z点的函数:

def z(x,y):
    return x+y
我希望生成3D绘图所需的显而易见的东西:对应Z值的二维numpy数组。我认为应该是这样的:

Z = np.array([[0, 1, 2, 3],
              [1, 2, 3, 4],
              [2, 3, 4, 5],
              [3, 4, 5, 6]])

我可以用几行代码来完成这项工作,但我正在寻找最简洁、最优雅的代码

实现所需的一个非常简单的方法是从坐标生成
网格

X,Y = np.meshgrid(x,y)
z = X+Y
或更一般的:

z = f(X,Y)
甚至在一行中:

z = f(*np.meshgrid(x,y))
编辑

如果你的函数也可能返回一个常数,你必须以某种方式推断出结果应该具有的维度。如果您想继续使用
meshgrids
一种非常简单的方法是用以下方式重新编写函数:

def f(x,y):
   return x*0+y*0+a
其中,
a
将是常数
numpy
将为您处理尺寸。这看起来当然有点奇怪,所以你可以写

def f(x,y):
   return np.full(x.shape, a)

如果您真的想使用同时在标量和数组上工作的函数,那么最好使用@PaulPanzer的答案中的
np.vectorize

对于
array
意识到使用开放网格更经济的函数:

>>> import numpy as np
>>> 
>>> X = np.array([0,1,2,3])
>>> Y = np.array([0,1,2,3])
>>> 
>>> def z(x,y):
...     return x+y
... 
>>> XX, YY = np.ix_(X, Y)
>>> XX, YY
(array([[0],
       [1],
       [2],
       [3]]), array([[0, 1, 2, 3]]))
>>> z(XX, YY)
array([[0, 1, 2, 3],
       [1, 2, 3, 4],
       [2, 3, 4, 5],
       [3, 4, 5, 6]])
如果网格轴是范围,则可以使用
np.ogrid

>>> XX, YY = np.ogrid[:4, :4]
>>> XX, YY
(array([[0],
       [1],
       [2],
       [3]]), array([[0, 1, 2, 3]]))
如果函数未感知数组,可以使用
np.vectorize

>>> def f(x, y):
...    if x > y:
...        return x
...    else:
...        return -x
... 
>>> np.vectorize(f)(*np.ogrid[-3:4, -3:4])
array([[ 3,  3,  3,  3,  3,  3,  3],
       [-2,  2,  2,  2,  2,  2,  2],
       [-1, -1,  1,  1,  1,  1,  1],
       [ 0,  0,  0,  0,  0,  0,  0],
       [ 1,  1,  1,  1, -1, -1, -1],
       [ 2,  2,  2,  2,  2, -2, -2],
       [ 3,  3,  3,  3,  3,  3, -3]])

X,Y=np.meshgrid(X,Y);z=X+Y
。就是这样:)我很确定以前在StackOverflow上的某个地方有人问过这种问题,但我什么也没找到。在玩了meshgrids之后,发现有一些令人惊讶的行为。例如,如果函数返回标量常量:def f(x,y):返回1;如果z=f(x,y),则不会收到二维数组,但它只会将z设置为标量…@JSStuball,这是正确的。如果不告诉函数返回值的维度应该是什么,它就无法知道。请查看对我答案的编辑。