【发布时间】:2017-09-08 13:57:40
【问题描述】:
我有一个 1 和 0 的 Numpy 一维数组。例如
a = np.array([0,1,1,1,0,0,0,0,0,0,0,1,0,1,1,0,0,0,1,1,0,0])
如果连续 0 的长度小于阈值,我想将连续 0 替换为 1,让说 2。第一个和最后一个连续 0 将被排除。所以它会输出一个像这样的新数组
out: [0,1,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,0,0]
如果阈值为 4,则输出为
out: [0,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0]
我所做的是计算每个段的长度 我从this answer得到了这个解决方案
segLengs = np.diff(np.flatnonzero(np.concatenate(([True], a[1:]!= a[:-1], [True] ))))
out: [1,3,7,1,1,2,3,2,2]
然后找到小于阈值的段
gaps = np.where(segLengs <= threshold)[0]
gapsNeedPadding = gaps[gaps % 2 == 0]
然后循环 gapsNeedPadding 数组
itertools.groupby 也可以完成这项工作,但会有点慢
有没有更有效的解决方案?我更喜欢矢量化解决方案。速度是我需要的。我已经有了一个缓慢的解决方案,它通过数组循环
更新
尝试了@divakar 在this question 中提供的解决方案,但是当阈值较大时,它似乎无法解决我的问题。
numpy_binary_closing 和 binary_closing 有不同的输出。此外,这两个函数都不会从边界 + 阈值关闭
我在下面的代码中有什么错误吗?
import numpy as np
from scipy.ndimage import binary_closing
def numpy_binary_closing(mask,threshold):
# Define kernel
K = np.ones(threshold)
# Perform dilation and threshold at 1
dil = np.convolve(mask, K, mode='same') >= 1
# Perform erosion on the dilated mask array and threshold at given threshold
dil_erd = np.convolve(dil, K, mode='same') >= threshold
return dil_erd
threshold = 4
mask = np.random.rand(100) > 0.5
print(mask.astype(int))
out1 = numpy_binary_closing(mask, threshold)
out2 = binary_closing(mask, structure=np.ones(threshold))
print(out1.astype(int))
print(out2.astype(int))
print(np.allclose(out1,out2))
输出
[0 1 1 0 1 1 0 0 0 1 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 1 1 1 1 0 0 0 1 1 0 0 0 1 1 0 1 0 1 0 0 0 0 1 0 0 1 0 1 1 1 1 1 1 0 1 0 0 0 1 0 1 0 0 0 1 1 1 0 1 1 0 1 1 1 1 0 1 1 1 0 0 0 1 0 0 0 0 1 0 1 1 1]
[0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 0]
[0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 0]
False
【问题讨论】:
-
为什么最后两个
0s没有被替换? -
@Ev.Kounis 第一个和最后一个连续 0 将被排除
-
阈值是常数吗?
-
@DYZ 不是,可能是 2 到 100+
-
记得注明您可能从中获取任何代码的任何其他帖子。对于这篇文章,该代码段:
np.diff(np.f..看起来需要这样。