在numpy 2D矩阵中计算“孔”

时间:2019-03-29 05:48:08

标签: python numpy vectorization

给出一个1和0的2D矩阵,例如-

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

1表示块,0表示空白。 我希望计算孔数及其累积深度

当一列的长度短于其相邻两列的时间时,就会存在一个井,并假定边界以块(1s)填充。例如,填充边框,数组变为:

array([[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
       [1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1],
       [1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1],
       [1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1],
       [1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1],
       [1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1],
       [1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1],
       [1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1],
       [1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1],
       [1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1],
       [1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1],
       [1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1],
       [1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1],
       [1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1],
       [1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1]])
  • 孔数为 3 第1列,第4列和(9,10))。

  • 孔的深度为min(height(col_to_left), height(col_to_right)) - height(well_col)
    因此,在这种情况下,深度为 [1、1、7] 。因此,累积深度为1 + 1 + 7 = 9

我将如何找到这个?我想避免使用循环。

1 个答案:

答案 0 :(得分:0)

您可以使用argmax获取每列中第一个的位置。

# find absolute depths
d = X.argmax(0)
# correct columns that are all zero
v = np.take_along_axis(X, d[None], 0)
d[v[0]==0] = len(X)
# pad and compute the col to next col changes
d = np.diff(np.concatenate([[0], d, [0]]))
# exclude no change
chng, = np.where(d)
# find down changes
dwn = d[chng]>0
# wells are where we go down and the next non zero change is up
well = dwn[:-1]&~dwn[1:]
# map back to unfiltered indices for left and right walls
l, r = chng[:-1][well], chng[1:][well]
wells = np.c_[l+1, r]
wells
# array([[ 1,  1],
#       [ 4,  4],
#       [ 9, 10]])
# retrieve relative depths
depths = np.minimum(d[l], -d[r])
depths
# array([1, 1, 7])