【问题标题】:numpy masked ragged arraynumpy蒙面参差不齐的数组
【发布时间】:2018-09-28 11:29:49
【问题描述】:

我想用非标量 fill_value 填充一个 dtype 为 object 的屏蔽数组(因为我需要存储屏蔽不规则数组)。

这是一个二维数组的示例,其元素是一维 numpy 数组。当然,我希望 fill_value 是一个空数组。

import numpy as np

arr = np.array([
    [np.arange(10), np.arange(5), np.arange(3)],
    [np.arange(1),  np.arange(2), np.array([])],
])

marr = np.ma.array(arr)

marr.mask = [[True, False, False],
             [True, False, True]]
marr.fill_value = np.array([])

marr.filled()

不幸的是,它在最后一行产生了错误:

ValueError: could not broadcast input array from shape (0) into shape (2,3)

我可以手动提取掩码,并将其应用于逐个元素的算法;但这对我来说似乎不是正确的方向。

谢谢!

【问题讨论】:

    标签: python arrays numpy


    【解决方案1】:

    我不会指望MaskedArray 可以很好地处理对象 dtype 数组。 filled 正在尝试将填充值(一个数组)复制到 data 中的插槽子集。由于广播可能很棘手,即使没有遮罩层。

    查看完整的错误:

    In [39]: marr.filled()                                                                                                  
    ---------------------------------------------------------------------------
    ValueError                                Traceback (most recent call last)
    <ipython-input-39-219e016a84cf> in <module>
    ----> 1 marr.filled()
    
    /usr/local/lib/python3.6/dist-packages/numpy/ma/core.py in filled(self, fill_value)
       3718             result = self._data.copy('K')
       3719             try:
    -> 3720                 np.copyto(result, fill_value, where=m)
       3721             except (TypeError, AttributeError):
       3722                 fill_value = narray(fill_value, dtype=object)
    
    ValueError: could not broadcast input array from shape (0) into shape (2,3)
    

    np.copyto 尝试相互广播resultfill_valuem(掩码),然后将相应的(掩码==true)元素从fill_value 复制到result

    marr.datamarr.mask 都是 (2,3)。但是将 (0,) 形状广播到 (2,3) 是行不通的,而且也不是你想要的。

    使用标量填充有效,但不适用于数组(或列表)。

    In [56]: np.broadcast_to(np.array([]),(2,3))                                                                            
    ...
    ValueError: operands could not be broadcast together with remapped shapes [original->remapped]: (0,) and requested shape (2,3)
    

    将广播一个 (1,) 形状数组 -

    In [57]: np.broadcast_to(np.array([1]),(2,3))                                                                           
    Out[57]: 
    array([[1, 1, 1],
           [1, 1, 1]])
    

    但是填充的结果不是数组;这是一个标量:

    In [58]: marr.filled(np.array([1]))                                                                                     
    Out[58]: 
    array([[1, array([0, 1, 2, 3, 4]), array([0, 1, 2])],
           [1, array([0, 1]), 1]], dtype=object)
    

    有效的填充

    如果我定义一个 (1,) 对象 dtype 数组并将 (0,) 数组放入其中(作为对象),我可以使这个填充工作。

    In [97]: Ofill = np.array([None], object)                                                                               
    In [98]: Ofill[0] = np.array([])                                                                                        
    In [99]: Ofill                                                                                                          
    Out[99]: array([array([], dtype=float64)], dtype=object)
    In [100]: marr.filled(Ofill)                                                                                            
    Out[100]: 
    array([[array([], dtype=float64), array([0, 1, 2, 3, 4]),
            array([0, 1, 2])],
           [array([], dtype=float64), array([0, 1]),
            array([], dtype=float64)]], dtype=object)
    

    这是因为Ofill 可以广播到 (2,3) 而不会弄乱元素的形状

    In [101]: np.broadcast_to(Ofill,(2,3))                                                                                  
    Out[101]: 
    array([[array([], dtype=float64), array([], dtype=float64),
            array([], dtype=float64)],
           [array([], dtype=float64), array([], dtype=float64),
            array([], dtype=float64)]], dtype=object)
    

    这可行,但我不会说它漂亮(或推荐)。

    None 填充更漂亮,但即便如此我们也必须将其列在列表中:

    In [103]: marr.filled([None])                                                                                           
    Out[103]: 
    array([[None, array([0, 1, 2, 3, 4]), array([0, 1, 2])],
           [None, array([0, 1]), None]], dtype=object)
    

    【讨论】:

      【解决方案2】:

      已为函数“填充”提供了要为被屏蔽部分填充的值。

      import numpy as np
      arr = np.array([
          [np.arange(10), np.arange(5), np.arange(3)],
          [np.arange(1),  np.arange(2), np.array([])],
      ])
      marr = np.ma.array(arr)
      marr.mask = [[True, False, False],
                   [True, False, True]]
      marr.fill_value = np.array([])
      marr.filled(2) 
      

      这个版本的代码没有给出那个错误。

      【讨论】:

      • 您填充的是标量,而不是 OP 尝试使用的数组。
      • 类似marr.filled(np.arange(1)) 的东西可以用数组替换元素。
      • filled 不带参数使用fill_value
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-18
      • 1970-01-01
      • 1970-01-01
      • 2020-05-24
      • 1970-01-01
      相关资源
      最近更新 更多