Create a mask only in the first positions

I have an array:

a = np.array([[ 0,  1,  2,  0,  0,  0],
              [ 0,  4,  1, 35,  0, 10],
              [ 0,  0,  5,  4,  0,  4],
              [ 1,  2,  5,  4,  0,  4]])

I need to select only the first consecutive 0in each line:

[[  True   False  False  False  False  False]
 [  True   False  False  False  False  False]
 [  True   True   False  False  False  False]
 [  False  False  False  False  False  False]]

I'm trying to:

a[np.arange(len(a)), a.argmax(1): np.arange(len(a)), [0,0,0]] = True

But this is wrong.

+4
source share
3 answers

You can use np.cumsum.

Assumption: you search for zeros only at the beginning of each line.

a = np.array([[ 0,  1,  2,  0,  0,  0],
              [ 0,  4,  1, 35,  0, 10],
              [ 0,  0,  5,  4,  0,  4]])

a.cumsum(axis=1) == 0
array([[ True, False, False, False, False, False],
       [ True, False, False, False, False, False],
       [ True,  True, False, False, False, False]], dtype=bool)

Basis: Holds Trueuntil the cumulative amount is 0 on each row.

Error: An array with negative ints will crash. That is, for [-1, 1], this will be evaluated to Trueat position 1.

+2
source

np.minimum.accumulate a == 0 ( ); non zero False, , False - :

np.minimum.accumulate(a == 0, axis=1)
#array([[ True, False, False, False, False, False],
#       [ True, False, False, False, False, False],
#       [ True,  True, False, False, False, False],
#       [False, False, False, False, False, False]], dtype=bool)
+2

argmin + broadcasting -

(a==0).argmin(1)[:,None] > np.arange(a.shape[1])

1) :

In [207]: a
Out[207]: 
array([[ 0,  1,  2,  0,  0,  0],
       [ 0,  4,  1, 35,  0, 10],
       [ 0,  0,  5,  4,  0,  4],
       [ 1,  2,  5,  4,  0,  4]])

2)

In [208]: (a==0)
Out[208]: 
array([[ True, False, False,  True,  True,  True],
       [ True, False, False, False,  True, False],
       [ True,  True, False, False,  True, False],
       [False, False, False, False,  True, False]], dtype=bool)

3) , False, True . , , , argmin 0. , broadcasting , True True argmin. broadcasted-comparison , .

In [209]: (a==0).argmin(1)
Out[209]: array([1, 1, 2, 0])

In [210]: (a==0).argmin(1)[:,None] > np.arange(a.shape[1])
Out[210]: 
array([[ True, False, False, False, False, False],
       [ True, False, False, False, False, False],
       [ True,  True, False, False, False, False],
       [False, False, False, False, False, False]], dtype=bool)

In [196]: a = np.random.randint(0,9,(5000,5000))

In [197]: %timeit a.cumsum(axis=1) == 0 #@Brad Solomon
     ...: %timeit np.minimum.accumulate(a == 0, axis=1) #@Psidom
     ...: %timeit (a==0).argmin(1)[:,None] > np.arange(a.shape[1])
     ...: 
10 loops, best of 3: 69 ms per loop
10 loops, best of 3: 64.9 ms per loop
10 loops, best of 3: 32.8 ms per loop
+2
source

Source: https://habr.com/ru/post/1685961/


All Articles