【问题标题】:Fill up contiguous sequences of zeros with incrementing sequences用递增序列填充连续的零序列
【发布时间】:2021-11-29 13:10:05
【问题描述】:

是否可以在不迭代的情况下用 arange 填充零值:

初始数组:

array([128,   0, 128,   0,   0,   0, 128,   0,   0,   0,   0,   0,   0,
         0,   0, 128, 128,   0,   0, 128, 128, 128,   0,   0,   0,   0,
         0,   0,   0, 128,   0,   0,   0,   0,   0, 128,   0,   0, 128,
       128,   0,   0, 128,   0,   0,   0, 128,   0,   0, 128, 128,   0,
         0,   0, 128, 128], dtype=uint8)

新数组:

array([128,   0, 128,   0,   1,   2, 128,   0,   1,   2,   3,   4,   5,
         6,   7, 128, 128,   0,   1, 128, 128, 128,   0,   1,   2,   3,
         4,   5,   6, 128,   0,   1,   2,   3,   4, 128,   0,   1, 128,
       128,   0,   1, 128,   0,   1,   2, 128,   0,   1, 128, 128,   0,
         1,   2, 128, 128], dtype=uint8)

【问题讨论】:

  • 所以你想在不使用任何循环的情况下填充零值?
  • 它在 128 之间计算零。这是一个非常困难的模式。不要相信没有迭代过程是可能的
  • @WalissonCardoso 如果您熟悉这个技巧,这实际上相对简单:)

标签: python numpy matrix


【解决方案1】:

这行得通:

zeros = a == 0
idxs = np.arange(len(a))
zero_block_starts = np.diff(zeros, prepend = 0) == 1
ranges = idxs - np.maximum.accumulate(zero_block_starts * idxs)
result = a.copy()
result[zeros] = ranges[zeros]

结果:

>>> a
array([128,   0, 128,   0,   0,   0, 128,   0,   0,   0,   0,   0,   0,
         0,   0, 128, 128,   0,   0, 128, 128, 128,   0,   0,   0,   0,
         0,   0,   0, 128,   0,   0,   0,   0,   0, 128,   0,   0, 128,
       128,   0,   0, 128,   0,   0,   0, 128,   0,   0, 128, 128,   0,
         0,   0, 128, 128], dtype=uint8)

>>> result
array([128,   0, 128,   0,   1,   2, 128,   0,   1,   2,   3,   4,   5,
         6,   7, 128, 128,   0,   1, 128, 128, 128,   0,   1,   2,   3,
         4,   5,   6, 128,   0,   1,   2,   3,   4, 128,   0,   1, 128,
       128,   0,   1, 128,   0,   1,   2, 128,   0,   1, 128, 128,   0,
         1,   2, 128, 128], dtype=uint8)

不过,我会谨慎使用 uint8 dtype 数组,因为大于 256 个元素的间隙会溢出。

【讨论】:

  • 对于您的表达式zero_block_starts * idxs,使用wherezbs=np.where(zero_block_starts)[0]; vals=np.zeros(len(a),dtype=int); vals[wherezbs]=wherezbs 是否可以提高效率以避免相乘?
【解决方案2】:

我尝试递归地做到这一点

def rec_fill_zero(init_list, index, zero_count):
    if init_list[index] == 128:
        head = 128
        next_zero_count = 0
    else:
        head = zero_count
        next_zero_count = zero_count + 1

    if init_list.size - index > 1:
        init_list[index] = head
        rec_fill_zero(init_list, index + 1, next_zero_count)


def fill_zero(initial_array):
    new_array = initial_array.copy()
    rec_fill_zero(new_array, 0, 0)
    return new_array

结果:

>>> initial_array
array([128,   0, 128,   0,   0,   0, 128,   0,   0,   0,   0,   0,   0,
         0,   0, 128, 128,   0,   0, 128, 128, 128,   0,   0,   0,   0,
         0,   0,   0, 128,   0,   0,   0,   0,   0, 128,   0,   0, 128,
       128,   0,   0, 128,   0,   0,   0, 128,   0,   0, 128, 128,   0,
         0,   0, 128, 128], dtype=uint8)
>>> fill_zero(initial_array)
array([128,   0, 128,   0,   1,   2, 128,   0,   1,   2,   3,   4,   5,
         6,   7, 128, 128,   0,   1, 128, 128, 128,   0,   1,   2,   3,
         4,   5,   6, 128,   0,   1,   2,   3,   4, 128,   0,   1, 128,
       128,   0,   1, 128,   0,   1,   2, 128,   0,   1, 128, 128,   0,
         1,   2, 128, 128], dtype=uint8)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-18
    • 1970-01-01
    • 1970-01-01
    • 2011-06-29
    • 2014-12-30
    • 2022-12-29
    • 2016-06-28
    • 1970-01-01
    相关资源
    最近更新 更多