【问题标题】:How to find where in numpy array a zero element is preceded by at least N-1 consecutive zeros?如何在numpy数组中找到零元素前面至少有N-1个连续零?
【发布时间】:2019-01-17 17:34:38
【问题描述】:

给定一个 numpy 数组(为简单起见,让它成为一个位数组),我如何构造一个形状相同的新数组,其中 1 恰好位于原始数组中零的位置,前面至少N-1 个连续的零?

例如,实现函数nzeros 的最佳方法是什么,该函数有两个参数、一个numpy 数组和所需的最小连续零个数:

import numpy as np
a = np.array([0, 0, 0, 0, 1, 0, 0, 0, 1, 1])
b = nzeros(a, 3)

函数nzeros(a, 3) 应该返回

array([0, 0, 1, 1, 0, 0, 0, 1, 0, 0])

【问题讨论】:

  • 如果任一答案有效,请考虑接受一个?

标签: python arrays numpy


【解决方案1】:

方法#1

我们可以使用1D convolution -

def nzeros(a, n):
    # Define kernel for 1D convolution
    k = np.ones(n,dtype=int)

    # Get sliding summations for zero matches with that kernel
    s = np.convolve(a==0,k)

    # Look for summations that are equal to n value, which will occur for
    # n consecutive 0s. Remember that we are using a "full" version of
    # convolution, so there's one-off offsetting because of the way kernel
    # slides across input data. Also, we need to create 1s at places where
    # n consective 0s end, so we would need to slice out ending elements.
    # Thus, we would end up with the following after int dtype conversion
    return (s==n).astype(int)[:-n+1]

示例运行 -

In [46]: a
Out[46]: array([0, 0, 0, 0, 1, 0, 0, 0, 1, 1])

In [47]: nzeros(a,3)
Out[47]: array([0, 0, 1, 1, 0, 0, 0, 1, 0, 0])

In [48]: nzeros(a,2)
Out[48]: array([0, 1, 1, 1, 0, 0, 1, 1, 0, 0])

方法 #2

另一种解决方法,这可以被认为是1D 卷积方法的变体,将使用erosion,因为如果您查看输出,我们可以简单地侵蚀0s 的掩码开始直到n-1 地方。因此,我们可以使用scipy.ndimage.morphology's binary_erosion,它还允许我们使用其origin arg 指定内核中心的部分,因此我们将避免任何切片。实现看起来像这样 -

from scipy.ndimage.morphology import binary_erosion

out = binary_erosion(a==0,np.ones(n),origin=(n-1)//2).astype(int)

【讨论】:

  • 漂亮的解决方案,并且比 for 循环更有效。为了 OP,你介意解释一下卷积的作用,为什么我们要创建一个向量等吗?
  • @Lagerbaer 添加了一些 cmets。
  • 那是纯粹的美丽......
【解决方案2】:

使用 for 循环:

def nzeros(a, n):
  #Create a numpy array of zeros of length equal to n
  b = np.zeros(n)

  #Create a numpy array of zeros of same length as array a
  c = np.zeros(len(a), dtype=int)

  for i in range(0,len(a) - n):
    if (b == a[i : i+n]).all():  #Check if array b is equal to slice in a
      c[i+n-1] = 1

  return c

样本输出:

print(nzeros(a, 3))
[0 0 1 1 0 0 0 1 0 0]

【讨论】:

    猜你喜欢
    • 2018-10-23
    • 2014-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-12
    相关资源
    最近更新 更多