【问题标题】:Find a specific sequence in all the rows of a 2d array在二维数组的所有行中查找特定序列
【发布时间】:2021-09-23 23:29:00
【问题描述】:

我正在尝试在 python 中创建一个循环(或更多 python 方式)来检测特定序列何时发生在二维数组中,然后用另一个集合替换它。专门找到每行中的第一个 [0,1,1] 并将其替换为 [0.25,0.5,0.75] 之类的内容,以在 1 的边缘创建渐变。

例子:

a =[[0,0,0,0,0,0,0]
    [0,1,1,1,1,1,0]
    [0,1,1,1,1,1,0]
    [0,0,0,0,0,0,0]]

detectfunction(a,[0,1,1],[0.25,0.5,0.75])

output =[[0,  0 ,  0 ,  0,0,0,0]
        [0,0.25,0.5,0.75,1,1,0]
        [0,0.25,0.5,0.75,1,1,0]
        [0,  0 ,  0 ,  0,0,0,0]]

这是我当前的代码,仅适用于数据的一部分。边缘列表是我在 0,1 过渡之后真正想要切入的内容。

fr_len = 10
fringe = np.arange(0,1,1/fr_len)
fringecloud1 = []
for ind,val in enumerate(O1bitcloud_m):
    m = list(O1bitcloud_m[ind])
    if val[ind] == 0 and val[ind+1] == 1:
        startind = ind
        endind = ind+fr_len
        m[startind:endind] = fringe
        fringecloud1.append(m)
    else:
        fringecloud1.append(m)

提前谢谢你!!

【问题讨论】:

  • 在您的示例中,模式 [0, 1, 1] 不能与自身重叠。如果我们允许重叠模式,那么预期的输出是什么,例如用[0, 1, 0, 1, 0]替换[0, 1, 0]
  • 这是特定于 [0,1,1] 的情况,实际上它类似于 [0,0,0......0,1,1,1,1 ,1,....] 在大量的 1 之前有大量的零,然后又回到零。
  • 我知道这是一个简化的例子。我的观点是可以有不同的方法来执行替换。顺便说一句,scipy.ndimage 模块在这里可能会有所帮助。

标签: python list multidimensional-array


【解决方案1】:

将操作拆分为三个任务及相关方法:

  1. 获取n个连续元素的组,与目标进行比较;
  2. 找到目标组的索引,先匹配;
  3. 用替换替换目标组。

这里的第一个方法是生成器返回一个列表,其中元素按n分组:

def each_cons(iterable, n = 2):
    if n < 2: n = 1
    i, size = 0, len(iterable)
    while i < size-n+1:
        yield iterable[i:i+n]
        i += 1

第二种方法,获取索引:

def find_idx_for_target(lst, target):
    for idx, sub in enumerate(each_cons(lst, n=len(target))):
        if sub == target:
            return idx
    return None

终于换人了:

def replace(lst, target, replacement):
    for sublst in lst:
        idx = find_idx_for_target(sublst, target)
        if idx is not None:
            sublst[idx:idx+len(replacement)] = replacement
    # add a check for len(target) == len(replacement)

例子:

a =[[0,0,0,0,0,0,0],
    [0,1,1,1,1,1,0],
    [0,1,1,1,1,1,0],
    [0,0,0,1,0,1,1]]
target = [0, 1, 1]
replacement = [0, 2, 2]

replace(a, target, replacement)

a

#[[0, 0, 0, 0, 0, 0, 0],
# [0, 2, 2, 1, 1, 1, 0],
# [0, 2, 2, 1, 1, 1, 0],
# [0, 0, 0, 1, 0, 2, 2]]

【讨论】:

    【解决方案2】:

    这是使用内置 array 模块的一种方法。通过将a 的行表示为Python 数组,我们可以直接在表示每一行的字节上调用replace。结果与您的预期输出不完全匹配(我不确定为什么示例输出的第 2 行和第 3 行中有前导零)。

    a =[[0,0,0,0,0,0,0],
        [0,1,1,1,1,1,0],
        [0,1,1,1,1,1,0],
        [0,0,0,0,0,0,0],]
    
    import array
    
    def detectfunction(a, pattern, subst):
      pattern_bytes = array.array('d', pattern).tobytes()
      subst_bytes   = array.array('d', subst).tobytes()
      
      result = list()
      for row in a:
        arr_row = array.array('d', row)
        new_arr_row = array.array('d', [])
        new_arr_row.frombytes(arr_row.tobytes().replace(pattern_bytes, subst_bytes))
        result.append(new_arr_row.tolist())
      
      return result
    
    result = detectfunction(a,[0,1,1],[0.25,0.5,0.75])
    
    # [[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
    #  [0.25, 0.5, 0.75, 1.0, 1.0, 1.0, 0.0],
    #  [0.25, 0.5, 0.75, 1.0, 1.0, 1.0, 0.0],
    #  [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]]
    

    【讨论】:

    • 这太棒了!它工作得很好!在我按照这个方向而不是为此编写一个新函数(无论如何我可能需要这样做)之后,我将我的数据填充了 90,180,270 度以在所有四个方面进行。我在它们重叠的地方有一些条纹,但我想我可以解决这个问题
    • 很高兴听到。如果它解决了您的问题,请随时接受答案。我也认为有一些优化的空间,特别是如果你输入的数组有一个非常特殊的形式(零后面跟着零)。
    猜你喜欢
    • 1970-01-01
    • 2023-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-23
    • 1970-01-01
    • 2021-02-02
    • 2013-01-25
    相关资源
    最近更新 更多