You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现布尔数组中按最小长度合并True块的二进制闭运算?

解决方案

要实现将夹在两个长度达标(≥指定最小值)的连续True序列之间的单个False替换为True的需求,可以通过以下基于NumPy的高效方法实现——scipy.ndimage.binary_closing无法满足需求,因为它无法针对True序列长度做条件判断:

核心思路

  1. 识别数组中所有连续True块的起始、结束位置及长度;
  2. 筛选出相邻的、长度均达标的True块,且它们之间仅隔一个False的情况;
  3. 将这些符合条件的单个False位置设为True。

实现代码

import numpy as np

def close(a, min_merge_size):
    # 处理空数组边界情况
    if len(a) == 0:
        return a.copy()
    
    # 扩展数组,便于处理首尾的True块
    extended_a = np.concatenate([[False], a, [False]])
    # 计算差分,找出True块的起始和结束点
    diff_a = np.diff(extended_a.astype(int))
    starts = np.where(diff_a == 1)[0]  # 每个True块的起始索引(对应原数组)
    ends = np.where(diff_a == -1)[0]   # 每个True块的结束索引+1(对应原数组)
    block_lengths = ends - starts      # 每个True块的长度
    
    # 若不足两个True块,直接返回原数组
    if len(block_lengths) < 2:
        return a.copy()
    
    # 矢量化筛选符合条件的gap:相邻块长度达标,且仅隔一个False
    valid_pairs = (block_lengths[:-1] >= min_merge_size) & \
                  (block_lengths[1:] >= min_merge_size) & \
                  (starts[1:] - ends[:-1] == 1)
    # 获取需要替换的False索引
    fill_indices = ends[:-1][valid_pairs]
    
    # 生成结果数组
    result = a.copy()
    result[fill_indices] = True
    return result

测试示例

a = np.array([True] *3 + [False] + [True] *4 + [False] *2 + [True] *2)
closed_a = close(a, min_merge_size=2)
print(closed_a)
# 输出:array([ True,  True,  True,  True,  True,  True,  True,  True, False, False,  True,  True])

为什么不用scipy.ndimage.binary_closing?

binary_closing的逻辑是先膨胀再腐蚀,仅基于结构元素的形状填充孔洞,无法判断两侧True序列的长度是否达标,也无法区分“单个False gap”和“多个False gap”,因此无法满足你的精确需求。

内容的提问来源于stack exchange,提问作者Jon Nir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 05:40:25