关于scipy中uniform_filter函数的注意事项

关于scipy中uniform_filter函数的注意事项

在处理分组聚合问题时,有时需要使用均值作为统计量。那其实就是一个均值滤波问题。我不希望使用for循环和均值卷积核来对二维数组进行滤波,因为这个线性运算且可用通过数字搬移来实现。

在使用uniform_filter时在边界处会出现难以解释的值,不过后来发现是我对python语法不够熟悉导致的。例如以下代码:

import numpy as np
x = np.array([[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]])

# 均值滤波
from scipy.ndimage import uniform_filter
y = uniform_filter(x, size=3,mode='reflect')

print(y)

他的输出结果是:
[[ 2 3 4 5 5]
[ 6 7 8 9 9]
[11 12 13 14 14]
[16 17 18 19 19]
[19 20 21 22 22]]
那么根据反射复制填充,当核运行到x的第一个元素1,核中元素应该是:
| 1 | 1 | 2 |
| 1 | 1 | 2 |
| 6 | 6 | 7 |
则均值的计算结果应该是3,为什么结果输出的是2呢?

这是因为定义的x数组是整型数组,uniform_filter会自动输出一个整数结果。由于uniform_filter在处理二维数组时,其实是多次一维滤波的结果平均,因此其实际的计算路径是:
∣ 1 ∣ 1 ∣ 2 ∣ → i n t ( 4 3 ) = 1 |1|1|2| \rightarrow int(\frac{4}{3})=1\\ ∣1∣1∣2∣int(34)=1 ∣ 1 ∣ 1 ∣ 2 ∣ → i n t ( 4 3 ) = 1 |1|1|2| \rightarrow int(\frac{4}{3})=1\\ ∣1∣1∣2∣int(34)=1 ∣ 6 ∣ 6 ∣ 7 ∣ → i n t ( 19 3 ) = 6 |6|6|7| \rightarrow int(\frac{19}{3}) = 6\\ ∣6∣6∣7∣int(319)=6
因此最后再求均值:
∣ 1 ∣ 1 ∣ 6 ∣ → i n t ( 8 3 ) = 2 |1|1|6|\rightarrow int(\frac{8}{3})=2 ∣1∣1∣6∣int(38)=2
也就是说,舍入误差导致了所有的问题
如果我们将数组转换为浮点型,则计算结果恢复正常:
[[ 3. 3.66666667 4.66666667 5.66666667 6.33333333]
[ 6.33333333 7. 8. 9. 9.66666667]
[11.33333333 12. 13. 14. 14.66666667]
[16.33333333 17. 18. 19. 19.66666667]
[19.66666667 20.33333333 21.33333333 22.33333333 23. ]]

你可能感兴趣的:(scipy)