3

我在这方面花了很多时间,而且我知道如何通过对边界行/列进行切片和索引来手动执行此操作,但是 SciPy 必须有一种更简单的方法。

我需要将CVAL(在 时填充超过边缘的值mode=constant)设置为 NaN,但是,这将返回 NaN。

我将用代码和数字来解释它:

import numpy as np
from scipy import ndimage
m = np.reshape(np.arange(0,100),(10,10)).astype(np.float)

输入数组的图片 使用 SciPy ndimage 统一滤波器使用 3x3 内核计算平均值:

filter = ndimage.uniform_filter(m, size=3, mode='constant')
print(filter[1][1]) # equal to 11
print(filter[9][9]) # I need 93.5, however it gets 41.55 due to zeros

如您所见,第一个值为 11,这与预期的一样,但是,对于沿边界的任何单元格,它将用零填充值(我也尝试了所有其他模式)。

这是我需要实现的(左)vsmode=constantCVAL=0(默认0)

scipy avg 和我需要什么

4

2 回答 2

2

一种简单的方法是使用归一化卷积

import numpy as np
from scipy import ndimage
m = np.reshape(np.arange(0,100),(10,10)).astype(np.float)

filter = ndimage.uniform_filter(m, size=3, mode='constant')    # normal filter result

weights = ndimage.uniform_filter(np.ones(m.shape), size=3, mode='constant')
filter = filter / weights    # normalized convolution result

print(filter[1][1]) # equal to 11
print(filter[9][9]) # equal to 93.49999999999994 -- rounding error! :)

weights如果所有数据点都是 1 ( ) ,我们计算了过滤器的结果。这显示了每个过滤器窗口中有多少数据元素,并在除边界附近以外的任何地方返回值 1,该值按比例减小。通过将过滤结果除以这些权重,我们校正了将数据域之外的零考虑在内的平均值。

于 2018-12-17T22:36:50.653 回答
1

这个建议不太理想,因为它会比 慢uniform_filter,但它会做你想做的事。

使用您使用常量值的想法,您可以通过使用而不是,作为通用过滤器函数nan来实现统一过滤器。ndimage.generic_filteruniform_filternumpy.nanmean

例如,这是您的示例数组m

In [102]: import numpy as np

In [103]: m = np.reshape(np.arange(0,100),(10,10)).astype(np.float)

Apply generic_filternumpy.nanmean作为要应用的函数:

In [104]: from scipy.ndimage import generic_filter

In [105]: generic_filter(m, np.nanmean, mode='constant', cval=np.nan, size=3)
Out[105]: 
array([[ 5.5,  6. ,  7. ,  8. ,  9. , 10. , 11. , 12. , 13. , 13.5],
       [10.5, 11. , 12. , 13. , 14. , 15. , 16. , 17. , 18. , 18.5],
       [20.5, 21. , 22. , 23. , 24. , 25. , 26. , 27. , 28. , 28.5],
       [30.5, 31. , 32. , 33. , 34. , 35. , 36. , 37. , 38. , 38.5],
       [40.5, 41. , 42. , 43. , 44. , 45. , 46. , 47. , 48. , 48.5],
       [50.5, 51. , 52. , 53. , 54. , 55. , 56. , 57. , 58. , 58.5],
       [60.5, 61. , 62. , 63. , 64. , 65. , 66. , 67. , 68. , 68.5],
       [70.5, 71. , 72. , 73. , 74. , 75. , 76. , 77. , 78. , 78.5],
       [80.5, 81. , 82. , 83. , 84. , 85. , 86. , 87. , 88. , 88.5],
       [85.5, 86. , 87. , 88. , 89. , 90. , 91. , 92. , 93. , 93.5]])
于 2018-12-17T21:14:57.457 回答