为numpy数组的每个"其他"字段((i + j)%2 == 0)添加值

Nic*_*mer 9 python arrays numpy matrix

我有一个m-by- nnumpy的数组,我想补充1.0的所有条目[i, j]的时候(i + j) % 2 == 0,即"每平方等".

我当然可以简单地遍历字段

import numpy as np

a = np.random.rand(5, 4)

for i in range(a.shape[0]):
    for j in range(a.shape[1]):
        if (i + j) % 2 == 0:
            a[i, j] += 1.0
Run Code Online (Sandbox Code Playgroud)

但不用说这真的很慢.

知道怎么改进这个吗?

Nil*_*ner 7

您可以通过两个步骤轻松完成操作,例如

import numpy as np

a = np.zeros((5, 14))

# Even rows, odd columns
a[::2, 1::2] += 1
# Odd rows, even columns
a[1::2, ::2] += 1

print a
Run Code Online (Sandbox Code Playgroud)


Div*_*kar 5

这是使用的一种方式NumPy broadcasting-

a[(np.arange(a.shape[0])[:,None] + np.arange(a.shape[1]))%2==0] += 1
Run Code Online (Sandbox Code Playgroud)

说明:我们基本上创建了两个i-thj-th迭代器等效的数组.让我们把它们IJ.

I = np.arange(a.shape[0])
J = np.arange(a.shape[1])
Run Code Online (Sandbox Code Playgroud)

现在,执行所有可能的之间的操作ij,我们创建延伸I2D推压它的元素到第一轴,从而创造沿其第二轴线单尺寸.

形象地说,广播的效果可以这样:

    I[:,None] : M , 1
            J : 1 , N
I[:,None] + J : M,  N
Run Code Online (Sandbox Code Playgroud)

因此,最终的设定是 -

a[(I[:,None] + J)%2==0] += 1
Run Code Online (Sandbox Code Playgroud)

换句话说,其目的是避免与基本比较0和直接使用mod-2基本上01-

a += (np.arange(a.shape[0])[:,None]-1 + np.arange(a.shape[1]))%2
Run Code Online (Sandbox Code Playgroud)

也可以np.ix_用来处理奇数行和偶数行进行设置,如下所示 -

a[np.ix_(np.arange(0,a.shape[0],2),np.arange(0,a.shape[1],2))] += 1
a[np.ix_(np.arange(1,a.shape[0],2),np.arange(1,a.shape[1],2))] += 1
Run Code Online (Sandbox Code Playgroud)