Python scipy.ndimage.filters.maximum_filter中的NAN

Python scipy.ndimage.filters.maximum_filter中的NAN,python,filter,scipy,max,Python,Filter,Scipy,Max,我不太了解在maximum_filter函数中对NAN的处理。我希望nan要么被忽略,要么更好,如果nan出现在内核的任何地方,结果就是nan。相反,根据外表的不同,南安人似乎受到不同的对待 问题似乎有点类似于 下面是一些使用scipy版本0.19.1完成的示例代码: import numpy as np import scipy.ndimage.filters a = np.array([[ 0, 0., 1., 2., 3., 4.],

我不太了解在maximum_filter函数中对NAN的处理。我希望nan要么被忽略,要么更好,如果nan出现在内核的任何地方,结果就是nan。相反,根据外表的不同,南安人似乎受到不同的对待

问题似乎有点类似于

下面是一些使用scipy版本0.19.1完成的示例代码:

    import numpy as np
    import scipy.ndimage.filters

    a = np.array([[    0,     0.,   1.,   2.,   3.,   4.],
                  [    0., np.nan,   1.,   2.,   3.,   2.],
                  [    0.,     0.,   1.,   2.,   3.,   4.],
                  [    1.,     0.,   1.,   2.,   3.,   4.]])

    b = np.array([[np.nan,     0.,   1.,   2.,   3.,   4.],
                  [    0.,     0,   1.,   2.,   3.,   2.],
                  [    0.,     0.,   1.,   2.,   3.,   4.],
                  [    1.,     0.,   1.,   2.,   3.,   4.]])

    c = np.array([[np.nan,     0.,   1.,   2.,   3.,   4.],
                  [    0., np.nan,   1.,   2.,   3.,   2.],
                  [    0.,     0.,   1.,   2.,   3.,   4.],
                  [    1.,     0.,   1.,   2.,   3.,   4.]])


    print(scipy.ndimage.filters.maximum_filter(a, size=3))
    print(scipy.ndimage.filters.maximum_filter(b, size=3))
    print(scipy.ndimage.filters.maximum_filter(c, size=3))
输出

    [[ 0.  1.  2.  3.  4.  4.]
     [ 0.  1.  2.  3.  4.  4.]
     [ 1.  1.  2.  3.  4.  4.]
     [ 1.  1.  2.  3.  4.  4.]]
    [[ nan  nan   2.   3.   4.   4.]
     [ nan  nan   2.   3.   4.   4.]
     [  1.   1.   2.   3.   4.   4.]
     [  1.   1.   2.   3.   4.   4.]]
    [[ nan  nan   2.   3.   4.   4.]
     [ nan  nan   2.   3.   4.   4.]
     [  1.   1.   2.   3.   4.   4.]
     [  1.   1.   2.   3.   4.   4.]]
在“a”中,忽略了NAN,而在“b”中,似乎与NAN的每次比较都会得到NAN和“c”中与“b”完全相同的结果

问题:
1.这是一个bug还是行为可以被证明是合理的?
2.如何获得不在左上角的nan的“b”结果?

尽量避免使用未明确说明其具有特殊
nan
处理的函数的
nan
s。它不是数字,所以不要在需要数字的地方使用它! SciPys
maximum_filter
就是其中之一

我曾考虑过进入SciPy内部,但由于这些都是实现细节,可能会在没有通知或反对的情况下更改,因此可能不值得这么做。此外,它还将非常复杂,因为它取决于比较的顺序和比较本身,以及函数如何执行
maximum\u filter
(我怀疑它们使用基于堆的运行maximum filter)

然而,你当然可以得到想要的结果。如果希望忽略
NaN
s,可以使用
-np.inf
替换它们(对于
maximum_filter
),如果希望“传播”它们,则可以使用通用过滤器:

def maximum_filter_ignore_nan(array, *args, **kwargs):
    nans = np.isnan(array)
    replaced = np.where(nans, -np.inf, array)
    return scipy.ndimage.filters.maximum_filter(replaced, *args, **kwargs)


def maximum_filter_propagate_nan(array, *args, **kwargs):
    def inner(array):
        if np.isnan(array).any():
            return np.nan
        return array.max()
    return scipy.ndimage.generic_filter(arr, inner, size=3)

print(maximum_filter_ignore_nan(a, size=3))
print(maximum_filter_ignore_nan(b, size=3))
print(maximum_filter_ignore_nan(c, size=3))

print(maximum_filter_propagate_nan(a, size=3))
print(maximum_filter_propagate_nan(b, size=3))
print(maximum_filter_propagate_nan(c, size=3))
尽量避免使用未明确说明其具有特殊
nan
处理的函数。它不是数字,所以不要在需要数字的地方使用它! SciPys
maximum_filter
就是其中之一

我曾考虑过进入SciPy内部,但由于这些都是实现细节,可能会在没有通知或反对的情况下更改,因此可能不值得这么做。此外,它还将非常复杂,因为它取决于比较的顺序和比较本身,以及函数如何执行
maximum\u filter
(我怀疑它们使用基于堆的运行maximum filter)

然而,你当然可以得到想要的结果。如果希望忽略
NaN
s,可以使用
-np.inf
替换它们(对于
maximum_filter
),如果希望“传播”它们,则可以使用通用过滤器:

def maximum_filter_ignore_nan(array, *args, **kwargs):
    nans = np.isnan(array)
    replaced = np.where(nans, -np.inf, array)
    return scipy.ndimage.filters.maximum_filter(replaced, *args, **kwargs)


def maximum_filter_propagate_nan(array, *args, **kwargs):
    def inner(array):
        if np.isnan(array).any():
            return np.nan
        return array.max()
    return scipy.ndimage.generic_filter(arr, inner, size=3)

print(maximum_filter_ignore_nan(a, size=3))
print(maximum_filter_ignore_nan(b, size=3))
print(maximum_filter_ignore_nan(c, size=3))

print(maximum_filter_propagate_nan(a, size=3))
print(maximum_filter_propagate_nan(b, size=3))
print(maximum_filter_propagate_nan(c, size=3))

我是否理解正确,因为即使在python中实现也很差,所以它归结为:“永远不要使用NAN!”?对于+/-inf,情况是否也是如此?这也不是一个数字。答案并不能解决我的问题,但还是要谢谢。@B.Biehler不,你可以使用
nan
s,例如NumPy有很多
np.nan*
函数,例如。还有+/-inf是一个数字!只是南斯的行为(有时)很奇怪。问题在于nan不等于任何东西(甚至不等于它本身),与nan的任何比较都应该返回false。这打破了许多对所有其他数字(甚至是inf)都有效的假设。@B.Biehler我用一些备选方案更新了答案,您可以使用这些备选方案来构建预期结果。我是否理解正确,它归结为:“永远不要使用NaN!”,因为即使在python中实现也很差?对于+/-inf,情况是否也是如此?这也不是一个数字。答案并不能解决我的问题,但还是要谢谢。@B.Biehler不,你可以使用
nan
s,例如NumPy有很多
np.nan*
函数,例如。还有+/-inf是一个数字!只是南斯的行为(有时)很奇怪。问题在于nan不等于任何东西(甚至不等于它本身),与nan的任何比较都应该返回false。这打破了对所有其他数字(甚至是inf)都有效的大量假设。@B.Biehler我用一些备选方案更新了答案,您可以使用这些备选方案来归档预期结果。