简体   繁体   中英

How to find the index of a list element in a numpy array using ranges

Say I have a numpy array as follows:

arr = np.array([[[1, 7], [5, 1]], [[5, 7], [6, 7]]])

where each of the innermost sub-arrays is an element. So for example; [1, 7] and [5, 1] are both considered elements.

... and I would like to find all the elements which satisfy: [<=5, >=7]. So, a truthy result array for the above example would look as follows:

arr_truthy = [[True, False], [True, False]]

... as for one of the bottom elements in arr the first value is <=5 and the second is >=7 .

I can solve this easily by iterating over each of the axes in arr :

    for x in range(arr.shape[0]):
        for y in range(arr.shape[1]):
            # test values, report if true.

.. but this method is slow and I'm hoping there's a more numpy way to do it. I've tried np.where but I can't work out how to do the multi sub-element conditional.

I'm effectively trying to test an independent conditional on each number in the elements.

Can anyone point me in the right direction?

Are you looking for

(arr[:,:,0] <= 5) & (arr[:,:,1] >= 7)

? You can perform broadcasted comparison.

Output:

array([[True, False],
       [True, False]])

I would do it like this. Initialize output to the same shape. Then just do the comparison on those elements.

out = np.full(arr.shape,False)
out[:,:,0] = arr[:,:,0] >= 5
out[:,:,1] = arr[:,:,1] >= 8

Output:

array([[[False, False],
        [ True, False]],

       [[ True,  True],
        [ True, False]]])

EDIT: After our edit I think you just need a final np.all along the last axis:

np.all(out, axis=-1)

Returns:

array([[False, False],
       [ True, False]])

In your example the second pair ( [5, 1] ) matches your rule (the first value is >=5 and the second is <=7), but in the result( arr_truthy ) its value is False. My code works if this was a mistake, otherwise please clarify the condition.

arr = np.array([[[1, 7], [5, 1]], [[5, 6], [6, 7]], [[1, 9], [9, 1]]])

# Create True/False arrays for the first/second element of the input
first = np.zeros_like(arr, dtype=bool)
first = first.flatten()
first[::2] = 1
first = first.reshape(arr.shape)
second = np.invert(first)

# The actual logic:
out = np.logical_or(np.where(arr >= 5, first, False), np.where(arr <= 7, second, False))
# Both the condition for the first and for the second element of each par has to be meet
out = out.all(axis=-1)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM