【问题标题】:NumPy masked array not considering fill_value when comparing to scalar与标量比较时,NumPy 掩码数组不考虑填充值
【发布时间】:2018-02-21 09:54:29
【问题描述】:

我有一个屏蔽的 numpy 数组,如下所示:

mar = np.ma.array([0, 0, 100, 100], mask=[False, True, True, False], fill_value=-1)

所以中间的两个值被屏蔽了,调用mar.filled()会返回[0, -1, -1, 100]

我想将此数组与标量 0 进行比较,即:

mar == 0

返回

masked_array(data = [True -- -- False],
             mask = [False  True  True False],
       fill_value = True)

请注意,fill_value 现在是 True,这是 bool 数组的默认填充值,但在这种情况下对我来说没有意义(我本来希望它设置为 -1 == 0,即 @987654330 @)。

为了更清楚地说明我的问题:(mar == 0).filled()mar.filled() == 0 不会返回相同的结果。

这是预期的行为还是错误?无论如何,是否有解决方法来实现我想要的行为?我知道我可以在使用.filled() 进行比较之前转换为普通数组,但如果可能的话我想避免这种情况,因为代码不应该关心它是屏蔽数组还是普通数组。

【问题讨论】:

    标签: python numpy


    【解决方案1】:

    mar == 0 使用mar.__eq__(0)

    该方法的文档说:

    当任何一个元素被屏蔽时,结果也会被屏蔽, 但底层布尔数据仍然设置,self和other 如果两者都被屏蔽,则认为相等,否则不相等。

    该方法又使用mar._comparison

    这首先对.data属性进行比较

    In [16]: mar.data
    Out[16]: array([  0,   0, 100, 100])
    In [17]: mar.data == 0
    Out[17]: array([ True,  True, False, False])
    

    然后它会比较掩码并调整值。 0 没有被屏蔽,所以它的“掩码”是False。由于mar的被屏蔽元素的掩码为True,所以掩码不匹配,比较.data设置为False。

    In [19]: np.ma.getmask(0)
    Out[19]: False
    In [20]: mar.mask
    Out[20]: array([False,  True,  True, False])
    In [21]: (mar==0).data
    Out[21]: array([ True, False, False, False])
    

    在比较中我得到了不同的fill_value。这可能是 v 1.14.0 的变化。

    In [24]: mar==0
    Out[24]: 
    masked_array(data=[True, --, --, False],
                 mask=[False,  True,  True, False],
           fill_value=-1)
    In [27]: (mar==0).filled()
    Out[27]: array([True, -1, -1, False], dtype=object)
    

    这令人困惑。掩码数组上的比较(通常是大多数函数)必须处理.data、掩码和填充。不知道 ma 的 Numpy 代码通常适用于 .data 并忽略屏蔽。 ma 方法可以使用filled() 值或compressed。这个comparison 方法尝试将所有 3 个属性都考虑在内。


    用掩码 0 数组(相同的掩码和填充值)测试相等性:

    In [34]: mar0 = np.ma.array([0, 0, 0, 0], mask=[False, True, True, False], fill_
        ...: value=-1)
    In [35]: mar0
    Out[35]: 
    masked_array(data=[0, --, --, 0],
                 mask=[False,  True,  True, False],
           fill_value=-1)
    In [36]: mar == mar0
    Out[36]: 
    masked_array(data=[True, --, --, False],
                 mask=[False,  True,  True, False],
           fill_value=-1)
    In [37]: _.data
    Out[37]: array([ True,  True,  True, False])
    

    mar == 0mar == np.ma.array([0, 0, 0, 0], mask=False) 相同

    【讨论】:

      【解决方案2】:

      我不知道为什么(mar == 0) 没有产生所需的输出。不过可以考虑

      np.equal(mar, 0)
      

      保留原来的填充值。

      【讨论】:

      • 这会返回[True, -1, -1, False],这也不是我想要的。我想要的输出是[True, False, False, False](就像在做mar.filled() == 0时一样)。
      猜你喜欢
      • 1970-01-01
      • 2014-10-10
      • 2011-08-31
      • 2021-02-10
      • 1970-01-01
      • 2019-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多