在numpy中优雅地生成结果数组
我有我的X和Y 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 = 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,这是正确的。如果不告诉函数返回值的维度应该是什么,它就无法知道。请查看对我答案的编辑。