如何枚举不包括第一行和最后一行和列的二维 NumPy 数组?

How do I enumerate a 2-dimensional NumPy array excluding the first and last rows and columns?

我想枚举二维 NumPy 数组的元素,不包括第一行和最后一行和列(即下面矩阵中的元素)。

import numpy as np

q = np.zeros((4, 4))
q[1, 1] = 1
q[1, 2] = 1
q[2, 1] = 1
q[2, 2] = 1

# [[0. 0. 0. 0.]
#  [0. 1. 1. 0.]
#  [0. 1. 1. 0.]
#  [0. 0. 0. 0.]]

我可以使用枚举每个元素并向第一个和最后一个添加条件检查 row/column 但这看起来很粗糙:

for ij, q_ij in np.ndenumerate(q):
    print(ij, q_ij)

当我切掉第一列和最后一列和行时 ij 相差一个

for ij, q_ij in np.ndenumerate(q[1:-1, 1:-1]):
    i, j = ij
    original_ij = (i + 1, j + 1)
    print(original_ij, ij, q_ij)

# (1, 1) (0, 0) 1.0
# (1, 2) (0, 1) 1.0
# (2, 1) (1, 0) 1.0
# (2, 2) (1, 1) 1.0

我显然可以调整 ij 以正确引用原始矩阵。为了清楚起见,我正在尝试计算标量场(例如温度)的拉普拉斯算子

laplacian[i][j] = q[i+1][j] + q[i-1][j] + q[i][j+1] + q[i][j-1] - 4*a[i][j]

需要避开边界元素

有没有更优雅的方法来做到这一点?

我觉得没有更“优雅”的形式了,老实说,我会使用基本的 range(1,q_ij-1)* ,但最后都是我们的编程方式,只是用形式你更舒服,工作得更好

范围(开始,停止[,步骤])

构造带切片赋值的数组:

In [164]: arr = np.zeros((4,4),int)
In [165]: arr[1:3,1:3] = np.arange(1,5).reshape(2,2)
In [166]: arr
Out[166]: 
array([[0, 0, 0, 0],
       [0, 1, 2, 0],
       [0, 3, 4, 0],
       [0, 0, 0, 0]])

由于您打印了每个元素,因此在所需索引上的双循环与 ndenumerate(或任何其他 'hides' 索引)一样好:

In [167]: for i in range(1,3):
     ...:     for j in range(1,3):
     ...:         print(f'({i},{j}) {arr[i,j]}')
     ...: 
(1,1) 1
(1,2) 2
(2,1) 3
(2,2) 4

用坐标一个一个地打印数组的元素一点也不优雅。

编辑

q[i+1][j] + q[i-1][j] + q[i][j+1] + q[i][j-1] - 4*a[i][j]

可以用slices改写成这样(不对可能不对)

q[2:4,1:3] - q[0:2,1:3] + ... - 4*a[1:3, 1:3]

我的目标是对基本差分计算进行二维扩展:

In [178]: x = np.array([1,0,3,2,0,1])
In [179]: x[1:] - x[:-1]
Out[179]: array([-1,  3, -1, -2,  1])

这就是np.diff(x).

scipy.signal 中有一个可能适用的 convolve 函数。我见过别人用过,但我自己没用过。

https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.convolve.html