我正在尝试用complex(x,y)
填充2D数组,其中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数组的自然起点。
答案 0 :(得分:2)
In [4]: xstep = np.linspace(0, 1, 2)
In [5]: ystep = np.linspace(0, 1, 3)
In [6]: xstep[:, None] + 1j*ystep
Out[6]:
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)
的二维数组。
In [19]: xstep[:, None].shape
Out[19]: (2, 1)
因此, xstep[:, None] + 1j*ystep
是形状为(2, 1)
的2D数组和形状为(3,)
的1D数组之和。
NumPy broadcasting通过自动在左侧添加新的轴(长度为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 ]])
答案 1 :(得分:1)
将reshape(-1,1)
的{{1}}用作:
xstep
答案 2 :(得分:1)
您可以将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
行表示创建一个开放的2D网格。轴0:0至1,2步,轴1:0至1,3步。切片“步骤”的类型充当开关,如果它是虚构的(实际上是任何复杂类型的对象),则其绝对值将被使用,并且该表达式被视为linspace。否则,将应用范围语义。
返回值
y, x
# (array([[0.],
# [1.]]), array([[0. , 0.5, 1. ]]))
“广播准备就绪”,因此在示例中,我们可以简单地将它们添加并获得完整的2D网格。
如果我们在第二个切片中允许我们自己使用一个假想的“停止”参数(仅适用于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 ]])