python - numpy 屏蔽不规则数组

标签 python arrays numpy

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

这是一个 2D 数组的示例,其元素是 1D 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)

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

谢谢!

最佳答案

我不会指望 MaskedArray 能够很好地处理对象数据类型数组。 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(掩码),并且然后将相应的 (mask==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,) 对象数据类型数组,并将 (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)

关于python - numpy 屏蔽不规则数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52554388/

相关文章:

c - 尝试更新数组元素时出错

numpy - 如何使用 numpy 创建这个非常规 "identity matrix"

python - numpy - 用 0 调整数组大小

python - Numpy:如何添加两个从不同类型转换而来的 np?

python - 如何检测足球场的绿道和边界?

python - 如何模拟绑定(bind)方法进行内省(introspection)

python - .png 是 python 的 tkinter 模块唯一可接受的格式吗?

ruby - 将n维数组的每个元素乘以Ruby中的数字

python - 使用命名参数作为变量

javascript - 根据 JavaScript 中的键值查找和删除数组中的对象