动态改变 scipys ndimage 过滤器中的过滤器大小
Dynamically varying the filter size in the scipys ndimage filters
在 How exactly does the “reflect” mode for scipys ndimage filters work? and Numpy Two-Dimensional Moving Average 之后,我有一个二维数组:
a
=>
np.array([[ 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.]])
当我使用 mode=constant
和 3x3 filter size
:
uniform_filter(a, size=3, mode='constant')
结果是:
=>
array([[ 1.33333333, 2.33333333, 3. , 3.66666667, 2.66666667],
[ 3.66666667, 6. , 7. , 8. , 5.66666667],
[ 7. , 11. , 12. , 13. , 9. ],
[ 10.33333333, 16. , 17. , 18. , 12.33333333],
[ 8. , 12.33333333, 13. , 13.66666667, 9.33333333]])
我了解此过滤器的内部工作原理,因为我在上面发布的链接中对其进行了很好的解释。
我的问题是,是否可以将数组中每个位置的总和除以值大于零的元素总数?
因此,例如,在我的数组中位置 [0,0] 中元素为 0
,元素 (0, 0, 0, 0, 0, 1, 0, 5, 6)
的总和将除以 3
(仅位置 [0,1] = 1
、[1,0] = 5
和 [1,1] = 6
的值大于零)而不是 9
。在数组的 [0,1] 位置,我将除以 5
。在位置 [0,2],我除以 6
,在位置 [1,2],我除以 9
。
在这种情况下,我的回答应该是;
=>
array([[ 4.0 , 4.2 , 4.5 , 5.5 , 6.0 ],
[ 6.60, 6.75, 7.0 , 8.0 , 8.5 ],
[ 10.5, 11. , 12. , 13. , 13.5 ],
[ 15.5, 16. , 17. , 18. , 18.5 ],
[ 18.0, 18.5, 19.5, 20.5, 21.0 ]])
这是一种方法 -
from scipy.ndimage.filters import uniform_filter
from scipy.signal import convolve2d
size = 3
kernel = np.ones((size,size),dtype=int)
nonzero_count = convolve2d(a!=0, kernel,'same')
windowed_sum = uniform_filter(a, size=size, mode='constant')*size**2
out = windowed_sum/nonzero_count
步骤:
获取形状滑动 windows 中的非零数:(size,size)
沿输入数组的行和列。
为此,我们可以使用 2D
卷积,所有 ones
的内核与内核具有相同的形状。或者,我们也可以使用 uniform_filter
获得非零计数:uniform_filter((a!=0).astype(float), size=size, mode='constant')*size**2
.
通过重新使用 uniform_filter
输出的平均值并按 size**2
缩放来获得滑动求和。或者,我们可以在这里再次使用 2D
卷积与 convolve2d(a, kernel,'same')
.
最后,将这些总和除以非零计数,即所需的输出。
样本输入、中间输出和最终输出 -
In [51]: a
Out[51]:
array([[ 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.]])
In [53]: nonzero_count
Out[53]:
array([[3, 5, 6, 6, 4],
[5, 8, 9, 9, 6],
[6, 9, 9, 9, 6],
[6, 9, 9, 9, 6],
[4, 6, 6, 6, 4]])
In [54]: windowed_sum
Out[54]:
array([[ 12., 21., 27., 33., 24.],
[ 33., 54., 63., 72., 51.],
[ 63., 99., 108., 117., 81.],
[ 93., 144., 153., 162., 111.],
[ 72., 111., 117., 123., 84.]])
In [55]: out
Out[55]:
array([[ 4. , 4.2 , 4.5 , 5.5 , 6. ],
[ 6.6 , 6.75, 7. , 8. , 8.5 ],
[ 10.5 , 11. , 12. , 13. , 13.5 ],
[ 15.5 , 16. , 17. , 18. , 18.5 ],
[ 18. , 18.5 , 19.5 , 20.5 , 21. ]])
在 How exactly does the “reflect” mode for scipys ndimage filters work? and Numpy Two-Dimensional Moving Average 之后,我有一个二维数组:
a
=>
np.array([[ 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.]])
当我使用 mode=constant
和 3x3 filter size
:
uniform_filter(a, size=3, mode='constant')
结果是:
=>
array([[ 1.33333333, 2.33333333, 3. , 3.66666667, 2.66666667],
[ 3.66666667, 6. , 7. , 8. , 5.66666667],
[ 7. , 11. , 12. , 13. , 9. ],
[ 10.33333333, 16. , 17. , 18. , 12.33333333],
[ 8. , 12.33333333, 13. , 13.66666667, 9.33333333]])
我了解此过滤器的内部工作原理,因为我在上面发布的链接中对其进行了很好的解释。
我的问题是,是否可以将数组中每个位置的总和除以值大于零的元素总数?
因此,例如,在我的数组中位置 [0,0] 中元素为 0
,元素 (0, 0, 0, 0, 0, 1, 0, 5, 6)
的总和将除以 3
(仅位置 [0,1] = 1
、[1,0] = 5
和 [1,1] = 6
的值大于零)而不是 9
。在数组的 [0,1] 位置,我将除以 5
。在位置 [0,2],我除以 6
,在位置 [1,2],我除以 9
。
在这种情况下,我的回答应该是;
=>
array([[ 4.0 , 4.2 , 4.5 , 5.5 , 6.0 ],
[ 6.60, 6.75, 7.0 , 8.0 , 8.5 ],
[ 10.5, 11. , 12. , 13. , 13.5 ],
[ 15.5, 16. , 17. , 18. , 18.5 ],
[ 18.0, 18.5, 19.5, 20.5, 21.0 ]])
这是一种方法 -
from scipy.ndimage.filters import uniform_filter
from scipy.signal import convolve2d
size = 3
kernel = np.ones((size,size),dtype=int)
nonzero_count = convolve2d(a!=0, kernel,'same')
windowed_sum = uniform_filter(a, size=size, mode='constant')*size**2
out = windowed_sum/nonzero_count
步骤:
获取形状滑动 windows 中的非零数:
(size,size)
沿输入数组的行和列。 为此,我们可以使用2D
卷积,所有ones
的内核与内核具有相同的形状。或者,我们也可以使用uniform_filter
获得非零计数:uniform_filter((a!=0).astype(float), size=size, mode='constant')*size**2
.通过重新使用
uniform_filter
输出的平均值并按size**2
缩放来获得滑动求和。或者,我们可以在这里再次使用2D
卷积与convolve2d(a, kernel,'same')
.最后,将这些总和除以非零计数,即所需的输出。
样本输入、中间输出和最终输出 -
In [51]: a
Out[51]:
array([[ 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.]])
In [53]: nonzero_count
Out[53]:
array([[3, 5, 6, 6, 4],
[5, 8, 9, 9, 6],
[6, 9, 9, 9, 6],
[6, 9, 9, 9, 6],
[4, 6, 6, 6, 4]])
In [54]: windowed_sum
Out[54]:
array([[ 12., 21., 27., 33., 24.],
[ 33., 54., 63., 72., 51.],
[ 63., 99., 108., 117., 81.],
[ 93., 144., 153., 162., 111.],
[ 72., 111., 117., 123., 84.]])
In [55]: out
Out[55]:
array([[ 4. , 4.2 , 4.5 , 5.5 , 6. ],
[ 6.6 , 6.75, 7. , 8. , 8.5 ],
[ 10.5 , 11. , 12. , 13. , 13.5 ],
[ 15.5 , 16. , 17. , 18. , 18.5 ],
[ 18. , 18.5 , 19.5 , 20.5 , 21. ]])