Python 使用两个np.linspace,如何用复杂值填充二维数组?
我试图用Python 使用两个np.linspace,如何用复杂值填充二维数组?,python,python-3.x,numpy,Python,Python 3.x,Numpy,我试图用复数(x,y)填充二维数组,其中x和y来自两个数组: xstep = np.linspace(xmin, xmax, Nx) ystep = np.linspace(ymin, ymax, Ny) 但是,我不知道如何在2D数组上“分散”这些值 到目前为止,我的尝试并没有真正奏效。我希望有一些类似的东西: result = np.array(xstep + (1j * ystep)) 可能是来自fromfunction、meshgrid或full的内容,但我不能完全让它工作 例如,假设
复数(x,y)
填充二维数组,其中x
和y
来自两个数组:
xstep = np.linspace(xmin, xmax, Nx)
ystep = np.linspace(ymin, ymax, Ny)
但是,我不知道如何在2D数组上“分散”这些值
到目前为止,我的尝试并没有真正奏效。我希望有一些类似的东西:
result = np.array(xstep + (1j * ystep))
可能是来自fromfunction
、meshgrid
或full
的内容,但我不能完全让它工作
例如,假设我这样做:
xstep = np.linspace(0, 1, 2) # array([0., 1.])
ystep = np.linspace(0, 1, 3) # array([0. , 0.5, 1. ])
我正试图构建一个答案:
array([
[0+0j, 0+0.5j, 0+1j],
[1+0j, 1+0.5j, 1+1j]
])
请注意,我没有嫁给linspace
,因此任何更快的方法也可以,这只是我创建这个数组的自然起点,对Numpy来说是新的。使用重塑(-1,1)
对于xstep
,如下所示:
xstep = np.linspace(0, 1, 2) # array([0., 1.])
ystep = np.linspace(0, 1, 3) # array([0. , 0.5, 1. ])
result = np.array(xstep.reshape(-1,1) + (1j * ystep))
result
array([[0.+0.j , 0.+0.5j, 0.+1.j ],
[1.+0.j , 1.+0.5j, 1.+1.j ]])
对xstep
使用重塑(-1,1)
,如下所示:
xstep = np.linspace(0, 1, 2) # array([0., 1.])
ystep = np.linspace(0, 1, 3) # array([0. , 0.5, 1. ])
result = np.array(xstep.reshape(-1,1) + (1j * ystep))
result
array([[0.+0.j , 0.+0.5j, 0.+1.j ],
[1.+0.j , 1.+0.5j, 1.+1.j ]])
xstep[:,None]
相当于xstep[:,np.newaxis]
,其目的是向右侧的xstep
添加一个新轴。因此,xstep[:,None]
是一个二维形状数组(2,1)
因此,xstep[:,None]+1j*ystep
是二维形状数组(2,1)
和一维形状数组(3,)
的总和
通过在左侧自动添加新轴(长度为1),解决此明显的形状冲突。因此,根据NumPy广播规则,1j*ystep
被提升为一个形状数组(1,3)
。
(请注意,xstep[:,None]
需要在右侧显式添加新轴,但广播会自动在左侧添加轴。这就是为什么1j*ystep[None,:]
虽然有效,但没有必要。)
广播进一步将两个阵列提升为公共形状(2,3)
(但采用内存有效的方式,无需复制数据)。沿长度为1的轴重复广播值:
In [15]: X, Y = np.broadcast_arrays(xstep[:, None], 1j*ystep)
In [16]: X
Out[16]:
array([[0., 0., 0.],
[1., 1., 1.]])
In [17]: Y
Out[17]:
array([[0.+0.j , 0.+0.5j, 0.+1.j ],
[0.+0.j , 0.+0.5j, 0.+1.j ]])
xstep[:,None]
相当于xstep[:,np.newaxis]
,其目的是向右侧的xstep
添加一个新轴。因此,xstep[:,None]
是一个二维形状数组(2,1)
因此,xstep[:,None]+1j*ystep
是二维形状数组(2,1)
和一维形状数组(3,)
的总和
通过在左侧自动添加新轴(长度为1),解决此明显的形状冲突。因此,根据NumPy广播规则,1j*ystep
被提升为一个形状数组(1,3)
。
(请注意,xstep[:,None]
需要在右侧显式添加新轴,但广播会自动在左侧添加轴。这就是为什么1j*ystep[None,:]
虽然有效,但没有必要。)
广播进一步将两个阵列提升为公共形状(2,3)
(但采用内存有效的方式,无需复制数据)。沿长度为1的轴重复广播值:
In [15]: X, Y = np.broadcast_arrays(xstep[:, None], 1j*ystep)
In [16]: X
Out[16]:
array([[0., 0., 0.],
[1., 1., 1.]])
In [17]: Y
Out[17]:
array([[0.+0.j , 0.+0.5j, 0.+1.j ],
[0.+0.j , 0.+0.5j, 0.+1.j ]])
您可以将
np.ogrid
与虚构的“步骤”一起使用,以获得linspace语义:
y, x = np.ogrid[0:1:2j, 0:1:3j]
y + 1j*x
# array([[0.+0.j , 0.+0.5j, 0.+1.j ],
# [1.+0.j , 1.+0.5j, 1.+1.j ]])
这里的ogrid
线意味着创建一个开放的二维网格。轴0:0到1,2步,轴1:0到1,3步。切片“step”的类型充当开关,如果它是虚构的(实际上是复杂类型的任何东西),则取其绝对值,并将表达式视为linspace。否则将应用范围语义
返回值
y, x
# (array([[0.],
# [1.]]), array([[0. , 0.5, 1. ]]))
是“广播就绪”,因此在示例中,我们可以简单地添加它们并获得完整的2D网格
如果我们在第二个片段中允许自己使用一个虚构的“stop”参数(该参数仅适用于linspace语义,因此根据您的风格,您可能更愿意避免它),则可以将其压缩为一行:
sum(np.ogrid[0:1:2j, 0:1j:3j])
# array([[0.+0.j , 0.+0.5j, 0.+1.j ],
# [1.+0.j , 1.+0.5j, 1.+1.j ]])
一种类似但可能性能更高的方法是预分配,然后广播:
out = np.empty((y.size, x.size), complex)
out.real[...], out.imag[...] = y, x
out
# array([[0.+0.j , 0.+0.5j, 0.+1.j ],
# [1.+0.j , 1.+0.5j, 1.+1.j ]])
另一个使用外和:
np.add.outer(np.linspace(0,1,2), np.linspace(0,1j,3))
# array([[0.+0.j , 0.+0.5j, 0.+1.j ],
# [1.+0.j , 1.+0.5j, 1.+1.j ]])
您可以将
np.ogrid
与虚构的“步骤”一起使用,以获得linspace语义:
y, x = np.ogrid[0:1:2j, 0:1:3j]
y + 1j*x
# array([[0.+0.j , 0.+0.5j, 0.+1.j ],
# [1.+0.j , 1.+0.5j, 1.+1.j ]])
这里的ogrid
线意味着创建一个开放的二维网格。轴0:0到1,2步,轴1:0到1,3步。切片“step”的类型充当开关,如果它是虚构的(实际上是复杂类型的任何东西),则取其绝对值,并将表达式视为linspace。否则将应用范围语义
返回值
y, x
# (array([[0.],
# [1.]]), array([[0. , 0.5, 1. ]]))
是“广播就绪”,因此在示例中,我们可以简单地添加它们并获得完整的2D网格
如果我们在第二个片段中允许自己使用一个虚构的“stop”参数(该参数仅适用于linspace语义,因此根据您的风格,您可能更愿意避免它),则可以将其压缩为一行:
sum(np.ogrid[0:1:2j, 0:1j:3j])
# array([[0.+0.j , 0.+0.5j, 0.+1.j ],
# [1.+0.j , 1.+0.5j, 1.+1.j ]])
一种类似但可能性能更高的方法是预分配,然后广播:
out = np.empty((y.size, x.size), complex)
out.real[...], out.imag[...] = y, x
out
# array([[0.+0.j , 0.+0.5j, 0.+1.j ],
# [1.+0.j , 1.+0.5j, 1.+1.j ]])
另一个使用外和:
np.add.outer(np.linspace(0,1,2), np.linspace(0,1j,3))
# array([[0.+0.j , 0.+0.5j, 0.+1.j ],
# [1.+0.j , 1.+0.5j, 1.+1.j ]])