[英]How to create a 3D (shape=m,n,o) array with ones along a specific (third) axis, the indices are given by a 2D array (shape=m,n)?
Let us say I have a 2D array with a shape (2, 2), containing indices 假设我有一个形状为(2,2)的2D数组,其中包含索引
x = np.array([[2, 0], [3, 1]])
What I would like to do is to create a 3D array with a shape (2, 2, 4), which has values 1 along the third axis, and their position is given by x
, therefore: 我想做的是创建一个形状为(2,2,4)的3D数组,该数组沿第三轴的值为1,其位置由x
给出,因此:
y = np.zeros(shape=(2,2,4))
myfunc(array=y, indices=x, axis=2)
array([[[0, 0, 1, 0],
[1, 0, 0, 0]],
[[0, 0, 0, 1],
[0, 1, 0, 0]]])
So far I have not found any indexing method for this. 到目前为止,我还没有找到任何索引方法。 A for
loop might be able to do this, but I am sure there is a faster, vectorized method. for
循环也许可以做到这一点,但是我确信有一个更快的矢量化方法。
What you are looking for is called advanced indexing . 您正在寻找的被称为高级索引 。 To index with integer arrays properly, you need to have a set of arrays that broadcast to the right shape. 为了正确地对整数数组建立索引,您需要具有一组广播为正确形状的数组。 Since x
is already lined up with two of the dimensions, you only need to make 2D arrays with the indices along each axis. 由于x
已经与其中的两个维度对齐,因此只需要制作2D数组,并在每个轴上都带有索引。 np.ogrid
helps with that since it creates minimal range arrays that broadcast to the correct shape: np.ogrid
可以帮助解决这个问题,因为它创建了最小范围的数组,可以广播为正确的形状:
a, b = np.ogrid[:2, :2]
y[a, b, x] = 1
The results of ogrid
are equivalent to ogrid
的结果等于
a = np.arange(2).reshape(-1, 1)
b = np.arange(2).reshape(1, -1)
Or 要么
a = np.arange(2)[:, None]
b = np.arange(2)[None, :]
You can also write a one-liner: 您还可以编写单行代码:
y[(*tuple(slice(None, n) for n in x.shape), x)] = 1
With for
loops: 使用for
循环:
y = np.zeros(shape=(2,2,4))
for i in range(2):
for j in range(2):
y[i,j,x[i,j]] = 1
With advanced indexing: 使用高级索引:
y = np.zeros(shape=(2,2,4))
i, j = np.meshgrid(np.arange(2), np.arange(2))
y[i,j,x[i,j]] = 1
Output (in both cases): 输出(在两种情况下):
array([[[0., 0., 1., 0.],
[1., 0., 0., 0.]],
[[0., 0., 0., 1.],
[0., 1., 0., 0.]]])
As for which will be actually faster, you need to try on your exact case... 至于实际上会更快,您需要尝试一下具体情况...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.