Как именно работает метод .any() Python?

Я пытаюсь написать скрипт, который имитирует систему химических реакций во времени. Одним из входных данных функции является следующий массив:

popul_num = np.array([200, 100, 0, 0])

Который содержит количество дискретных молекул каждого вида в системе. Часть основной функции содержит оператор if, предназначенный для проверки положительности числа молекул. if обрабатывается до следующей итерации, else выходит из всей симуляции

if popul_num.any() < 0: # Any method isn't working! --> Does .any() work on arrays or just lists? 
        print("Break out of loop negative molecule numbers")
        tao_all = tao_all[0:-1]
        popul_num_all = popul_num_all[0:-1]       
    else:
        break

Я использовал .any(), чтобы попытаться найти, является ли какой-либо элемент массива popul_num отрицательным. Но это не работает, не выдает ошибку, система просто никогда не вводит оператор if, и я не могу понять, почему?

Я только что запустил программу, и система вернула окончательное число молекул: [135 -19 65 54] программа должна была завершиться до того, как второй элемент достиг -19.

Какие-либо предложения?

Ваше здоровье


person Mike5298    schedule 27.06.2020    source источник
comment
any вернет True, если хотя бы один из элементов имеет значение True; any(iterable)   -  person Aditya    schedule 27.06.2020
comment
Просто сделайте if np.any(popul_num < 0): # do_stuff или if (popul_num < 0).any(): #do_stuff. Вы начинаете с построения логического массива перед применением any.   -  person alani    schedule 27.06.2020


Ответы (5)


Метод any массивов numpy возвращает логическое значение, поэтому, когда вы пишете:

if popul_num.any() < 0:

popul_num.any() будет либо True (=1), либо False (=0), поэтому никогда не будет меньше нуля. Таким образом, вы никогда не войдете в это if-оператор.

Что делает any(), так это оценивает каждый элемент массива как логическое значение и возвращает, является ли любой из них правдивым. Например:

>>> np.array([0.0]).any()
False

>>> np.array([1.0]).any()
True

>>> np.array([0.0, 0.35]).any()
True

Как видите, Python/numpy считает 0 ложным, а все остальные числа правдивыми. Таким образом, вызов any для массива чисел сообщает нам, является ли какое-либо число в массиве отличным от нуля. Но вы хотите знать, является ли какое-либо число отрицательным, поэтому сначала нам нужно преобразовать массив. Давайте введем отрицательное число в ваш массив для демонстрации.

>>> popul_num = np.array([200, 100, 0, -1])
>>> popul_num < 0  # Test is applied to all elements in the array
np.ndarray([False, False, False, True])
>>> (popul_num < 0).any()
True

Вы спрашивали о any списках и массивах. Встроенный в Python list не имеет метода any:

>>> [].any()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute 'any'

Существует встроенная функция (не метод, поскольку она не принадлежит классу) с именем any, который служит той же цели, что и метод numpy .any. Эти два выражения логически эквивалентны:

any(popul_num < 0)

(popul_num < 0).any()

Обычно мы ожидаем, что второй будет быстрее, поскольку numpy реализован в C. Однако только первый будет работать с типами, отличными от numpy, такими как list и set.

person ApproachingDarknessFish    schedule 27.06.2020

Вы должны использовать .any() для логического массива после выполнения сравнения, а не для самих значений popul_num. Он вернет True, если любое из значений логического массива равно True, иначе False.

На самом деле, .any() проверяет любые истинные значения, которые для целых чисел означают ненулевые значения, поэтому он будет работать с массивом целых чисел, чтобы проверить, являются ли какие-либо из них ненулевыми, что вы и делаете, но это не проверка то, что вам интересно знать. Затем код усугубляет проблему, выполняя тест < 0 для логического значения, возвращаемого any, который всегда оценивает True, поскольку логические значения обрабатываются как 0 и 1 (для False и True соответственно) в операциях с целыми числами.

Ты можешь сделать:

if (popul_num < 0).any():
    do_whatever

Здесь popul_num < 0 — логический массив, содержащий результаты поэлементного сравнения. В вашем примере:

>>> popul_num < 0
array([False, False, False, False], dtype=bool)

Однако вы правильно используете array.any() (или np.any(array)), а не встроенный any(). Последнее работает для одномерного массива, но не работает с большим количеством измерений. Это связано с тем, что итерация, например. над массивом 4d (что и сделал бы встроенный any()) дает последовательность массивов 3d, а не отдельных элементов.

Так же есть .all(). Приведенный выше тест эквивалентен:

if not (popul_num >= 0).all():
person alani    schedule 27.06.2020

any() — это метод для использования на итерируемых объектах. Он возвращает True, если какой-либо из элементов в итерации правдив. Вы хотите что-то большее, например:

if any([True for x in popul_num if x > 0]):
  print("at least one element was greater than zero!")
person Frank    schedule 27.06.2020

any() возвращает True, если хотя бы один из элементов имеет значение True:

L1 = [False, False, False]
any(L1)
# >>> False

L1 = [True, False, False]
any(L1)
# >>> True

L1 = ["Hi", False, False]
any(L1)
# >>> True

L1 = []
any(L1)
# >>> False

person CMinusMinus    schedule 27.06.2020

any() возвращает True, если хотя бы один элемент в массиве NumPy оценивается как True, а np.all проверяет, все ли элементы массива вдоль данной оси оцениваются как True. Что вам нужно, чтобы решить вашу проблему, это метод all.

person Mateo Lara    schedule 27.06.2020