问题描述
我想枚举二维 NumPy 数组的元素,不包括第一行和最后一行和列(即下面矩阵中的元素)。
yarn add path-browserify --dev
我可以使用枚举每个元素并向第一行和最后一行/列添加条件检查,但这似乎很粗糙:
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.]]
当我切掉第一列和最后一列和行时,for ij,q_ij in np.ndenumerate(q):
print(ij,q_ij)
和 i
相距一个
j
我显然可以调整 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
和 i
以正确引用原始矩阵。为了清晰起见,我试图计算标量场(例如温度)的拉普拉斯算子
j
并且需要避免边界元素。
有没有更优雅的方法来做到这一点?
解决方法
我认为没有更“优雅”的形式了,真诚的,我会使用基本的 range(1,q_ij-1)* ,但最后都是我们的编程方式,就用你更舒服的形式来做并且运行良好
range(start,stop[,step])
,使用切片赋值构造数组:
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,1,2,3,4,0]])
由于您打印每个元素,因此对所需索引进行双循环与 ndenumerate
(或任何其他“隐藏”索引)一样好:
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]
可以像这样用切片重写(defails可能不正确)
q[2:4,1:3] - q[0:2,1:3] + ... - 4*a[1:3,1:3]
我的目标是基本差异计算的二维扩展:
In [178]: x = np.array([1,1])
In [179]: x[1:] - x[:-1]
Out[179]: array([-1,-1,-2,1])
这就是np.diff(x)
。
在 scipy.signal
中有一个可能适用的 convolve
函数。我见过其他人使用它,但我自己没有。
https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.convolve.html