1

I have a 2D array like:

r1= np.array([[1,2,3,4],[2,3,4,5],[3,4,5,6]])

I need to find , for each row, the first occurence of a value greater than a default value. I am using this:

default=2
ans= np.argmax(r1>default,1)

The issue is that it works if there is a value greater than default but returns zero if such a value is not found. So it returns zero in 2 cases- 1) the first value in each row is greater than the default 2) no value in each is greater than default

#simple case:
In[31]: np.argmax(r1>2,1)
Out[31]: array([2, 1, 0], dtype=int64)

#trouble case- both returning zeros
In[32]: np.argmax(r1>7,1)
Out[32]: array([0, 0, 0], dtype=int64)
In[33]: np.argmax(r1>0.5,1)
Out[33]: array([0, 0, 0], dtype=int64)

I am currently using this to resolve this:

In[37]: np.any(r1>7,1) + np.argmax(r1>7,1)-1
Out[37]: array([-1, -1, -1], dtype=int64)
In[38]: np.any(r1>0.5,1) + np.argmax(r1>0.5,1)-1
Out[38]: array([0, 0, 0], dtype=int64)

Any other suggestions to simplify this?

dayum
  • 1,073
  • 15
  • 31

2 Answers2

1

a nested list(2d array) of form

l = [[n1,n2,n3],[m1,m2,m3]...]

can be traversed for first value in each nested list greater than given number 'd' using

[[i for i in x if i>d][0] for x in l]
  • Thanks, this is useful for the case where i want the actual value. Doesnt answer this question where i want the indices of those values and dont want an error in case the value isn't found. Still a good trick – dayum Nov 03 '16 at 06:30
  • sorry was not logged for a long time. can be done for indices too. `[y for y in [[x.index(i) for i in x if i>d] for x in l] if len(y)>0 ]` –  Dec 20 '16 at 14:43
0

Already looks pretty concise, to be honest. But here is an alternative I think might work:

ans = np.argmax(r1>default,1) - (np.amin(r1<=default,1))

The part at the end produces an array of booleans indicating when all the items in the row are below or equal to your default value.

Any False in the row (so any value that is above the default) makes the whole thing False. Only when all the values are below the default will we get a result of True.

Karnage
  • 677
  • 4
  • 9