[英]Sliding a subarray along a 2d array
This is something I've been struggling with for a couple of weeks. 这是我一直努力奋斗的事情。 The algorithm is the following: 该算法如下:
I've got steps 1 to 3 as follows: 我有步骤1到3,如下所示:
import numpy as np
w1 = np.arange(100).reshape(10,10)
side = 3
patch = w1[0:side, 0:side]
i, j = patch.shape
for j in range(side):
for i in range(side):
patch[i,j] = np.median(patch)
Eventually, I'll be using a 901x877 array from an image but I'm just trying to get a hold of this simple task first. 最终,我将使用图像中的901x877阵列,但我只是想首先抓住这个简单的任务。 How can I slide the array along and then down with a loop? 我如何才能使数组前后滑动并向下循环?
Here are a few "code smells" I see. 我看到了一些“代码气味”。 Start with the range(side)
since this number is set to 3
then you are going to have a result of [0,1,2]
. 因为这个数字设置为3
所以从range(side)
开始,您将得到[0,1,2]
的结果。 Is that what you really want? 那是你真正想要的吗?
you set i,j = patch.size
then immediately over write these values, in your for
loops. 您设置i,j = patch.size
然后在您的for
循环中立即覆盖这些值。
Finally, you're recalculating median
every loop. 最后,您要重新计算每个循环的median
。
Ok, here's what I'd do. 好的,这就是我要做的。
import numpy as np
w1 = np.arange(100).reshape(10,10)
side = 3
w, h = w1.shape
width_index = np.array(range(w//side)) * side
height_index = np.array(range(h//side)) * side
def assign_patch(patch, median, side):
"""Break this loop out to prevent 4 nested 'for' loops"""
for j in range(side):
for i in range(side):
patch[i,j] = median
return patch
for width in width_index:
for height in height_index:
patch = w1[width:width+side, height:height+side]
median = np.median(patch)
assign_patch(patch, median, side)
print w1
You can use scikit-image's view_as_blocks
and NumPy broadcasting to vectorize the operation: 您可以使用scikit-image的view_as_blocks
和NumPy广播对操作进行矢量化处理:
import numpy as np
import skimage
w1 = np.arange(144).reshape(12,12)
print(w1)
# [[ 0 1 2 3 4 5 6 7 8 9 10 11]
# [ 12 13 14 15 16 17 18 19 20 21 22 23]
# [ 24 25 26 27 28 29 30 31 32 33 34 35]
# [ 36 37 38 39 40 41 42 43 44 45 46 47]
# [ 48 49 50 51 52 53 54 55 56 57 58 59]
# [ 60 61 62 63 64 65 66 67 68 69 70 71]
# [ 72 73 74 75 76 77 78 79 80 81 82 83]
# [ 84 85 86 87 88 89 90 91 92 93 94 95]
# [ 96 97 98 99 100 101 102 103 104 105 106 107]
# [108 109 110 111 112 113 114 115 116 117 118 119]
# [120 121 122 123 124 125 126 127 128 129 130 131]
# [132 133 134 135 136 137 138 139 140 141 142 143]]
side = 3
w2 = skimage.util.view_as_blocks(w1, (side, side))
w2[...] = np.median(w2, axis=(-2, -1))[:, :, None, None]
print(w1)
# [[ 13 13 13 16 16 16 19 19 19 22 22 22]
# [ 13 13 13 16 16 16 19 19 19 22 22 22]
# [ 13 13 13 16 16 16 19 19 19 22 22 22]
# [ 49 49 49 52 52 52 55 55 55 58 58 58]
# [ 49 49 49 52 52 52 55 55 55 58 58 58]
# [ 49 49 49 52 52 52 55 55 55 58 58 58]
# [ 85 85 85 88 88 88 91 91 91 94 94 94]
# [ 85 85 85 88 88 88 91 91 91 94 94 94]
# [ 85 85 85 88 88 88 91 91 91 94 94 94]
# [121 121 121 124 124 124 127 127 127 130 130 130]
# [121 121 121 124 124 124 127 127 127 130 130 130]
# [121 121 121 124 124 124 127 127 127 130 130 130]]
Note that I had to change the size of your array to 12x12
so that all of your tiles of 3x3
actually fit in there. 请注意,我必须将数组的大小更改为12x12
以便所有3x3
的图块实际上都适合其中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.