Как найти индекс элемента списка в массиве numpy, используя диапазоны

#python #numpy

#python #numpy

Вопрос:

Допустим, у меня есть массив numpy следующим образом:

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

где каждый из самых внутренних подмассивов является элементом. Так, например; [1, 7] и [5, 1] оба считаются элементами.

… и я хотел бы найти все элементы, которые удовлетворяют: [<=5, >=7]. Итак, достоверный результирующий массив для приведенного выше примера будет выглядеть следующим образом:

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

… что касается одного из нижних элементов в arr первом значении <=5 , а второе — >=7 .

Я могу легко решить эту проблему, выполнив итерацию по каждой из осей в arr :

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

.. но этот метод медленный, и я надеюсь, что есть другой numpy способ сделать это. Я пробовал np.where , но не могу понять, как выполнить условие с несколькими подэлементами.

Я эффективно пытаюсь протестировать независимое условие для каждого числа в элементах.

Кто-нибудь может указать мне правильное направление?

Ответ №1:

Я бы сделал это так. Инициализируйте вывод в той же форме. Затем просто выполните сравнение этих элементов.

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

Вывод:

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

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

РЕДАКТИРОВАТЬ: После нашего редактирования, я думаю, вам просто нужен окончательный np.все вдоль последней оси:

 np.all(out, axis=-1)
 

ВОЗВРАТ:

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

Комментарии:

1. Извинения.. Я только что немного обновил свой вопрос.. но ваша логика все равно должна сохраняться. Я проверю это.

Ответ №2:

Вы ищете

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

? Вы можете выполнить широковещательное сравнение.

Вывод:

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

Комментарии:

1. Хотя ваш ответ правильный, вы поставили меня в известность о проблеме с моим вопросом. Я отредактирую его, чтобы уточнить.

2. обновлен ответ @desiguel, можете ли вы проверить, работает ли это?

3. Неплохо. Я проверю это.

Ответ №3:

В вашем примере вторая пара ( [5, 1] ) соответствует вашему правилу (первое значение >= 5, а второе <= 7), но в результате( arr_truthy ) его значение равно False . Мой код работает, если это была ошибка, в противном случае, пожалуйста, уточните условие.

 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)
 

Комментарии:

1. Неплохо. Спасибо за помощь, но два других ответа выглядят так, как будто они делают что-то похожее на ваше, более лаконично, используя сокращение фрагмента массива. На самом деле довольно круто.. сегодня я узнал, как нарезать массивы!