我有一个通过对数据帧应用不同搜索条件获得的布尔掩码列表。这是一个包含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]
答案 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位整数(然后可以很容易地将其转换为布尔掩码数组),并且您将无法轻松地运行到整数限制。