提问人:d.nikolai 提问时间:11/3/2023 最后编辑:d.nikolai 更新时间:11/4/2023 访问量:45
遍历 4-Dimensional Array 中的前两个索引?
Looping over first two indices in 4-Dimensional Array?
问:
我有一个尺寸为 478,533,3,3 的 np.array(变量标题为“window”,使用 NumPy stride tricks 从更大的 2D 数组滑动窗口生成)。数组的 478x535 部分基本上是 3x3 数组的数组。 我有兴趣遍历所有 3x3 数组以获取每个数组的 [1,1] 索引点的值(并执行一些条件操作)。我尝试了各种循环组合,但似乎无法找出用于遍历每个 3x3 数组的“for”循环。
window = np.lib.stride_tricks.sliding_window_view(tiff_array, (3,3))
P11 = np.zeros([3,3])
for i,j in window:
block = window[i,j,:,:]
if block[1,1]==1:
if block[1,1]-1==1 and block[1,1]-1==1:
P11[0,0]=P11[0,0]+1
这是我在各种尝试中尝试过的一些快速代码。我继续收到错误,即“有太多的值需要解压缩”,并且预计有两个(我想是 i,j)。我知道有两个以上的值,这就是我尝试遍历每个 3x3 数组块的原因。我想我错过了一些明显的东西,但希望得到一些帮助。 TIA!
答:
0赞
aerobiomat
11/3/2023
#1
您的方法适用于以下更改:
window = np.lib.stride_tricks.sliding_window_view(tiff_array, (3,3))
P11 = np.zeros([3,3])
for block in window.reshape(-1, 3, 3):
if block[1,1]==1:
if block[1,1]-1==1 and block[1,1]-1==1:
P11[0,0]=P11[0,0]+1
我不知道你真正需要做什么,但这种风格的矢量化方法通常更好:
t11 = tiff_array[1:-1, 1:-1]
ones = t11 == 1
P11[0, 0] = ones.sum()
...
t11
只是原始数组的视图,因此它不会花费额外的内存。
评论
0赞
d.nikolai
11/4/2023
谢谢!我认为这就是我正在寻找的 - 将 3x3 块的视图转换为原始主“tiff_array”。我正在尝试确定数组中每个 3x3 块的中心值,在中心值和周长值之间执行一些条件计算,然后在整个数组中以蛇形方式从一个块移动到下一个 3x3 块。因此,第一个块的中心位于 [1,1],下一个块的中心位于 [1,2],一直到 [478,533] 的中心。
0赞
hpaulj
11/4/2023
在滑动窗口视图上执行操作时要小心。它往往会增加内存使用量。reshape
0赞
aerobiomat
11/4/2023
同意。我只是想展示它是如何工作的。我自己不是sliding_window_view的忠实粉丝。
0赞
hpaulj
11/4/2023
#2
对于较小的起始阵列:
In [17]: arr = np.random.randint(1,4,(6,6))
In [18]: arr
Out[18]:
array([[1, 1, 2, 2, 2, 1],
[3, 2, 3, 2, 1, 1],
[2, 2, 3, 3, 1, 1],
[1, 2, 3, 3, 1, 1],
[3, 2, 3, 2, 3, 1],
[1, 3, 2, 1, 2, 1]])
In [19]: window = np.lib.stride_tricks.sliding_window_view(arr, (3,3))
In [20]: window.shape
Out[20]: (4, 4, 3, 3)
中心:
In [21]: window[:,:,1,1]
Out[21]:
array([[2, 3, 2, 1],
[2, 3, 3, 1],
[2, 3, 3, 1],
[2, 3, 2, 3]])
计算它们很容易:
In [22]: (window[:,:,1,1]==1).sum()
Out[22]: 3
正如评论的那样,我不知道你在总结什么。
但是让我们猜一猜,至少看看迭代块应该如何工作:
In [26]: P=np.zeros((3,3),int)
In [27]: for i in range(window.shape[0]):
...: for j in range(window.shape[1]):
...: block = window[i,j]
...: if block[1,1]==1:
...: print(block[0,1],block[2,1])
...: P += block
...:
2 1
1 1
1 3
In [28]: P
Out[28]:
array([[7, 4, 3],
[8, 3, 3],
[8, 5, 3]])
眯着眼睛侧头看,我几乎可以想象
if block[1,1]==1:
if block[1,1]-1==1 and block[1,1]-1==1:
只是意味着
block[1,1]==1 and block[1,0]==1 and block[1,2]==1
(block[1,:]==1).all()
也就是说,每个块的整行都是 1
In [66]: P=np.zeros((3,3),int)
...: for i in range(window.shape[0]):
...: for j in range(window.shape[1]):
...: block = window[i,j]
...: if (block[1,:]==1).all():
...: P[:] += block
...: P
Out[66]:
array([[0, 0, 0],
[0, 0, 0],
[0, 0, 0]])
在我的小样本中,没有任何大小为 3 的 1 序列。
评论
block[1,1]==1
block[1,1]-1==1
np.apply_along_axis
for i,j in window
不是你如何获得你使用的索引值,比如你需要一个和循环。然而,这种迭代感觉完全不对。window[i,j,]
for i in range(478)
for j
sliding window
478*533
apply_along...