逻辑或pandas掩码列表

时间:2015-08-21 04:12:47

标签: python numpy pandas

我有一个通过对数据帧应用不同搜索条件获得的布尔掩码列表。这是一个包含4个掩码的示例列表:

mask_list = [mask1, mask2, mask3, mask4]

我想找到列表中的逻辑或所有掩码。换句话说,

or_mask = mask_list[0] | mask_list[1] | mask_list[2] | mask_list[3]

对于包含任意数量掩码的列表,是否有一种简洁的方法可以实现此目的?我知道我可以编写一个for循环,如下所示,但有更短,更pythonic的方法吗?

for i in range(len(mask_list)):
    if i == 0:
        temp_mask_or = mask_list[i]
    else:
        temp_mask_or = temp_mask_or | mask_list[i]

2 个答案:

答案 0 :(得分:3)

您可以使用reduce:

or_(x,y)表示x|y,这样就可以了:

from operator import or_
or_mask = reduce(or_,mask_list)

编辑:正如JoeCondron所建议的那样,您可以使用operator.or_而不是numpy.logical_or,它会提供相同的结果但更快。

答案 1 :(得分:2)

在组合蒙版时,我通常会使用类似的循环,可能会略有不同:

combmask = mask_list[0]
for mask in mask_list[1:]:
    combmask |= mask

如果这还不够短,你可以使用你只是这些掩码的事实,并将它们视为整体(它们在引擎盖下):

combmask = np.array(sum(mask_list), dtype=np.bool)

如果你看sum(mask_list),你会发现它只是一个整数列表。

一个可能的警告,我不知道后一种方法,是当你试图总计超过255个掩码时它是否会遇到问题,其中至少有一个(相同的)元素总是True (即1)。存储np.bool的基础整数类型只有8位afaik,你可以通过这种方式达到整数限制。也许numpy / Python在继续之前会自动将所有内容转换为16位整数类型,但我不知道。

编辑:我会留下后者,但很容易检查:

In [51]: len(mask_list)
Out[51]: 4

In [52]: sum(mask_list).dtype
Out[52]: dtype('int64')

因此,即使将掩码的短列表的总和转换为64位整数(然后可以很容易地将其转换为布尔掩码数组),并且您将无法轻松地运行到整数限制。