使用NumPy在索引处设置值的更简洁方法

时间:2017-10-28 12:46:12

标签: python arrays numpy indexing

我最初有一个零的numpy数组,如下所示:

v = np.zeros((5, 5))
v

array([[ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.]])

我还有一组数组idx1idx2

idx1

array([[0, 3],
       [0, 4],
       [1, 3],
       [2, 4]])

idx2

array([[0, 1],
       [0, 2],
       [0, 4],
       [1, 3]])

将每对值视为行和列索引。因此,例如,在idx1中,第一对(0, 3)将成为v[0, 3]的索引器,依此类推。

我想首先在idx11指定的索引处设置值,然后是idx20指定的所有索引。

另请注意,如果某个数组中有一对(i, j),我想同时设置v[i, j]v[j, i]

我的最终结果是:

array([[ 0.,  0.,  0.,  1.,  0.],
       [ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  1.],
       [ 1.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  1.,  0.,  0.]])

我目前通过以下方式实现这一目标:

def set_vals(x, i, j, v):
    x[i, j] = x.T[i, j] = v

v = np.zeros((5, 5))

i1, j1 = idx1[:, 0], idx1[:, 1]
i2, j2 = idx2[:, 0], idx2[:, 1]

set_vals(v, i1, j1, 1)
set_vals(v, i2, j2, 0)

v     #  the result

但是,我相信可能有更好的方法。很想听到任何改进的想法/建议。谢谢!

1 个答案:

答案 0 :(得分:1)

寻找更多" compact"表达它的方式,我得到了这个 -

v = np.zeros((5, 5))
v[tuple(np.r_[idx1,idx1[:,::-1]].T)] = 1
v[tuple(np.r_[idx2,idx2[:,::-1]].T)] = 0

在python3.6 +上,您可以使用*解包运算符来进一步减少这一点:

v[[*np.r_[idx1,idx1[:,::-1]].T]] = 1
v[[*np.r_[idx2,idx2[:,::-1]].T]] = 0
v

array([[ 0.,  0.,  0.,  1.,  0.],
       [ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  1.],
       [ 1.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  1.,  0.,  0.]])