jeannej
jeannej

Reputation: 1183

Find indices where a python array becomes positive (but not negative)

I have a np.array similar to this one :

A = np.array([-1,-0.5,0.5,1,2,-2,-0.25,2,5])

I would like to get the indices where the array passes from negative to positive, but not the other way around (which would be achieved using np.sign methods). Hence, my desired output would be only :

ind = [1,6]

So far I tried things similar to this answer, but then I also index 4 which I do not want. My real array is rather large (about 10k elements) and the occurrence of sign changes is not regular. Thank you for your help !

Upvotes: 2

Views: 2393

Answers (2)

jeannej
jeannej

Reputation: 1183

Thank you @FBruzzesi for this hint! I followed your logic and used:

ch = np.where(A[:-1]*A[1:]<0)[0]
ch = ch[A[ch]<0]

which is easier to read for me, and also is slighly faster on my computer. Using timeit.repeat on 1000 iterations for an array with 10k element gives on average :

  • using booleans (@FBruzzesi answer) : 9.89E-02 sec
  • using array comparison (above) : 6.74E-02 sec

and of course I removed the tolist() on @FBruzzesi answer for the sake of honest comparison, so the two output are arrays (I didn't mind getting an array or list, but thank you for picking up this detail).

Thanks again!

Upvotes: 2

FBruzzesi
FBruzzesi

Reputation: 6475

You can both check that the product of consecutive elements of the array is negative and the corresponding value is negative (hence changing from negative to positive):

A = np.array([-1, -0.5, 0.5, 1, 2, -2, -0.25, 2, 5])

m1 = A[:-1]<0 
m2 = np.sign(A[1:]*A[:-1])==-1

r = np.argwhere(np.all(np.vstack([m1,m2]), axis=0))
ind = np.squeeze(r).tolist()

ind
[1, 6]

Upvotes: 2

Related Questions