python花式索引与布尔掩码数组

时间:2016-07-19 09:46:45

标签: python numpy indexing masked-array

我有一个numpy蒙面数据数组:

maxOpenConnections

我有一个特定类型数据的标志,这是一个布尔掩码数组:

data = masked_array(data = [7 -- 7 1 8 -- 1 1 -- -- 3 -- -- 3 --],
                    mask = [False True False False False True False False True True False True True False True])

我想做flag = masked_array(data = [True False False True -- -- -- False -- True -- -- -- -- True], mask = [False False False False True True True False True False True True True True False]) 之类的事情并获得以下输出:

data[flag]

对应于标志为True的数据元素。相反,我得到了这个:

output_wanted = [7 1 -- --]

为了更清晰,我没有复制输出的掩码。

我不介意输出具有标志大小的输出,只要它选择我想要的数据(对应于标志的True值的数据)。但我无法弄清楚为什么它会在实际输出中给出这些值!

3 个答案:

答案 0 :(得分:2)

如下:

import numpy as np
from numpy.ma import masked_array

data = masked_array(data = [7,     0,     7,     1,     8,     0,    1,     1,     0,    0,     3,     0,    0,    3,     0],
                    mask = [False, True,  False, False, False, True, False, False, True, True,  False, True, True, False, True])
flag = masked_array(data = [True,  False, False, True,  0,     0,    0,     False, 0,    True,  0,     0,    0,    0,     True],
                    mask = [False, False, False, False, True,  True, True,  False, True, False, True,  True, True, True,  False])

print(repr(data))
print(repr(flag))

indices = np.where(flag & ~flag.mask)
print(data[indices])

注意,如果flag中的屏蔽值无法与&进行比较,则可能会遇到麻烦,但对您来说情况并非如此。

输出:

masked_array(data = [7 -- 7 1 8 -- 1 1 -- -- 3 -- -- 3 --],
             mask = [False  True False False False  True False False  True  True False  True  True False  True],
       fill_value = 999999)

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

[7 1 -- --]

编辑:

获取指数的另一种方法可能是:

indices = np.where(flag.filled(False))

更新(编辑2):

注意使用数组索引数组的细微之处。

请考虑以下代码:

import numpy as np

data = np.array([1,2,3,4,5])
mask = np.array([True, False, True, False, True])

res  = data[mask]
print(res)

正如您可能(或可能不会)所期望的那样,这里的掩码用作“过滤器”,过滤掉掩码中相应位置为False的数据元素。由于我为datamask选择的值,效果是索引用于过滤掉偶数data值,只留下奇数值。

此处的输出为:[1 3 5]

现在,请考虑 非常 类似的代码:

import numpy as np

data = np.array([1,2,3,4,5])
mask = np.array([1, 0, 1, 0, 1])

res  = data[mask]
print(res)

这里,唯一改变的是掩码元素的数据类型,它们的布尔值是相同的。让我们调用第一个掩码(由True / False值组成)mask1和第二个掩码(由1 / 0值组成){{1} }。

您可以通过mask2属性(例如dtype)检查数组的数据类型。 print(mask.dtype)的dtype为mask1,而bool的dtype为mask2

但是,输出结果不同: int32

这里发生了什么?

实际上,索引的行为会有所不同,具体取决于用于索引的数组的数据类型。如上所述,当“mask”的数据类型为boolean时,它提供过滤功能。但是当“mask”的数据类型是完整的时,它会提供一个“选择”函数,使用索引的元素作为原始数组的索引。

因此,在第二个示例中,由于[2 1 2 1 2]data[1] = 2data[0] = 1的结果是一个长度为5的数组,而不是3(在布尔值的情况下)。

换句话说,给出以下代码:

data[mask2]

如果res = data[mask] ,res的长度将等于掩码的长度。

如果mask.dtype == int,则res的长度将等于掩码中mask.dtype == bool值的数量。

相当不同。

最后,您可以使用True方法将一种数据类型的数组强制转换为另一种数据类型。

演示片段:

astype

答案 1 :(得分:1)

如果我使用:

重建数组
In [28]: d=np.ma.masked_equal([7,0,7,1,8,0,1,1,0,0,3,0,0,3,0],0)

In [29]: f=np.ma.MaskedArray([True,False,False,True, False,False,False,False,True,True,True,True,True,True,True],[False, False, False, False, True, True, True, False, True, False, True, True, True, True, False])

In [30]: d
Out[30]: 
masked_array(data = [7 -- 7 1 8 -- 1 1 -- -- 3 -- -- 3 --],
             mask = [False  True False False False  True False False  True  True False  True
  True False  True],
       fill_value = 0)

In [31]: f
Out[31]: 
masked_array(data = [True False False True -- -- -- False -- True -- -- -- -- True],
             mask = [False False False False  True  True  True False  True False  True  True
  True  True False],
       fill_value = True)

屏蔽的显示匹配,但我猜测屏蔽的值是什么。

In [32]: d[f]
Out[32]: 
masked_array(data = [7 1 -- -- 3 -- -- 3 --],
             mask = [False False  True  True False  True  True False  True],
       fill_value = 0)

In [33]: d[f.data]
Out[33]: 
masked_array(data = [7 1 -- -- 3 -- -- 3 --],
             mask = [False False  True  True False  True  True False  True],
       fill_value = 0)

f建立索引与使用其data属性建立索引相同。它的面具什么也没做。显然我的蒙面价值与你的不同。

但如果我使用filled数组进行索引,我会得到所需的数组:

In [34]: d[f.filled(False)]
Out[34]: 
masked_array(data = [7 1 -- --],
             mask = [False False  True  True],
       fill_value = 0)
<{> fillednp.ma代码中被大量使用,具有不同的填充值,具体取决于np操作(例如0表示产品的总和v 1)。掩盖的数组通常不会跳过掩盖它们的值;相反,他们将蒙面的转换为无害的值,并使用常规的numpy操作。另一种策略是使用compressed删除屏蔽值。

在另一个答案中提到了

indices = np.where(flag.filled(False)),但是普通的布尔形式同样适用。

屏蔽数组具有datamask属性。屏蔽不会直接更改data值。该任务留给filled等方法。

答案 2 :(得分:0)

我弄清楚了如何使用屏蔽数组进行索引。

实际上,python并不处理这种索引。

当使用message = "blah\nblah" for line in message.split("\n"): logger.debug(message) data[flag]这样的布尔掩码数组进行操作时,python会获取flag的基础数据。换句话说,它在屏蔽之前采用屏蔽值的值。

请注意:如果屏蔽的值未明确用flag填充,则索引可能看起来是随机的。

示例:

fill_value

一种方法就像jedwards回答。

但我认为应该避免使用屏蔽数组来标记数据,但这并没有带来足够的洞察力。

如果标志数组用于访问某种类型的数据,则屏蔽值应设置为>>> arr = np.array([0, 1, 2, 3, 4]) >>> flag = np.ma.masked_array([True, False, False, True, True], [False, True, False, False, True]) >>> arr[flag]) array([0, 3, 4]) 。例如,如果要插入未标记的数据。

如果使用标志数组来屏蔽某种类型的数据,则应将屏蔽值设置为True。