编程语言
首页 > 编程语言> > python-向量化-添加没有循环的numpy数组?

python-向量化-添加没有循环的numpy数组?

作者:互联网

所以我有以下numpy数组:

c = array([[ 1,  2,  3],
           [ 4,  5,  6],
           [ 7,  8,  9],
           [10, 11, 12]])
X = array([[10, 15, 20,  5],
           [ 1,  2,  6, 23]])
y = array([1, 1])

我试图将X数组中的每个1×4行添加到c中的列之一. y数组指定哪一列.上面的示例意味着我们将X数组中的两行都添加到c的第1列.也就是说,我们应该期待以下结果:

     c = array([[ 1,  2+10+1,  3],  =  array([[ 1,  13,  3],
                [ 4,  5+15+2,  6],            [ 4,  22,  6],
                [ 7,  8+20+6,  9],            [ 7,  34,  9],
                [10, 11+5+23, 12]])           [10,  39, 12]])  

有谁知道我如何做到这一点而没有循环?我试过c [:,y] = X,但似乎只将X的第二行添加到c的第1列一次.话虽如此,应注意,y不必一定是[1,1],它也可以是[0,1].在这种情况下,我们将X的第一行添加到c的第0列,并将X的第二行添加到c的第1列.

解决方法:

当我看到所需的计算时,我的第一个想法是将X的两行相加,然后将其添加到c的第二列:

In [636]: c = array([[ 1,  2,  3],
           [ 4,  5,  6],
           [ 7,  8,  9],
           [10, 11, 12]])

In [637]: c[:,1]+=X.sum(axis=0)

In [638]: c
Out[638]: 
array([[ 1, 13,  3],
       [ 4, 22,  6],
       [ 7, 34,  9],
       [10, 39, 12]])

但是,如果我们要使用像y这样的通用索引,则需要特殊的无缓冲操作-也就是说,如果y中存在重复项:

In [639]: c = array([[ 1,  2,  3],
           [ 4,  5,  6],
           [ 7,  8,  9],
           [10, 11, 12]])

In [641]: np.add.at(c,(slice(None),y),X.T)

In [642]: c
Out[642]: 
array([[ 1, 13,  3],
       [ 4, 22,  6],
       [ 7, 34,  9],
       [10, 39, 12]])

您需要在numpy文档中查找.at.

在IPython的add.at?向我展示了包含以下内容的文档:

Performs unbuffered in place operation on operand ‘a’ for elements
specified by ‘indices’. For addition ufunc, this method is equivalent to
a[indices] += b, except that results are accumulated for elements that
are indexed more than once. For example, a[[0,0]] += 1 will only
increment the first element once because of buffering, whereas
add.at(a, [0,0], 1) will increment the first element twice.

用不同的y仍然有效

In [645]: np.add.at(c,(slice(None),[0,2]),X.T)

In [646]: c
Out[646]: 
array([[11,  2,  4],
       [19,  5,  8],
       [27,  8, 15],
       [15, 11, 35]])

标签:vectorization,arrays,python,numpy
来源: https://codeday.me/bug/20191118/2028816.html