我有以下numpy数组matrix
,
matrix = np.zeros((3,5), dtype = int)
array([[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]])
假设我有这个numpy数组indices
以及
indices = np.array([[1,3], [2,4], [0,4]])
array([[1, 3],
[2, 4],
[0, 4]])
问题:如何将1
分配给matrix
中由indices
数组指定其索引的元素。预计会进行矢量化实施。
为了更清晰,输出应如下所示:
array([[0, 1, 0, 1, 0], #[1,3] elements are changed
[0, 0, 1, 0, 1], #[2,4] elements are changed
[1, 0, 0, 0, 1]]) #[0,4] elements are changed
答案 0 :(得分:5)
以下是使用NumPy's fancy-indexing
-
matrix[np.arange(matrix.shape[0])[:,None],indices] = 1
<强>解释强>
我们使用np.arange(matrix.shape[0])
-
In [16]: idx = np.arange(matrix.shape[0])
In [17]: idx
Out[17]: array([0, 1, 2])
In [18]: idx.shape
Out[18]: (3,)
列索引已经以indices
-
In [19]: indices
Out[19]:
array([[1, 3],
[2, 4],
[0, 4]])
In [20]: indices.shape
Out[20]: (3, 2)
让我们制作行索引和列索引形状的示意图,idx
和indices
-
idx (row) : 3
indices (col) : 3 x 2
为了使用行索引和列索引索引到输入数组matrix
,我们需要使它们相互广播。一种方法是将新轴引入idx
,通过将元素推入第一个轴并使单个dim作为最后一个轴2D
来使其成为idx[:,None]
,如下所示 -
idx (row) : 3 x 1
indices (col) : 3 x 2
在内部,idx
将被广播,如此 -
In [22]: idx[:,None]
Out[22]:
array([[0],
[1],
[2]])
In [23]: indices
Out[23]:
array([[1, 3],
[2, 4],
[0, 4]])
In [24]: np.repeat(idx[:,None],2,axis=1) # indices has length of 2 along cols
Out[24]:
array([[0, 0], # Internally broadcasting would be like this
[1, 1],
[2, 2]])
因此,来自idx
的广播元素将用作indices
的行索引和列索引,用于索引到matrix
以设置其中的元素。因为,我们有 -
idx = np.arange(matrix.shape[0])
,
因此,我们最终会以 -
结束 matrix[np.arange(matrix.shape[0])[:,None],indices]
用于设置元素。
答案 1 :(得分:0)
这涉及循环,因此对于大型数组可能不是非常有效
for i in range(len(indices)):
matrix[i,indices[i]] = 1
> matrix
Out[73]:
array([[0, 1, 0, 1, 0],
[0, 0, 1, 0, 1],
[1, 0, 0, 0, 1]])