python, логический массив numpy: отрицание в операторе where - PullRequest
13 голосов
/ 14 февраля 2011

с:

import numpy as np
array = get_array()

Мне нужно сделать следующее:

for i in range(len(array)):
    if random.uniform(0, 1) < prob:
        array[i] = not array[i]

с массивом, представляющим собой numpy.array.

Хотелось бы сделать что-то похожее на:

array = np.where(np.random.rand(len(array)) < prob, not array, array)

но я получаю следующий результат (ссылаясь на 'not array'):

Значение истинности массива с более чем одним элементом неоднозначно. Используйте a.any () или a.all ()

Почему я могу принять значение массива, но не его отрицание?

В настоящее время я решил с помощью:

array = np.where(np.random.rand(len(array)) < prob, - array + 1, array)

но мне это кажется очень неуклюжим.

Спасибо за вашу помощь

p.s .: Мне все равно, изменяет ли оператор массив или нет. Мне просто нужен результат операции.

просто еще один вопрос: я хочу сделать это изменение по двум причинам: удобочитаемость и эффективность. Есть ли реальное улучшение производительности с ним? Еще раз спасибо

Ответы [ 3 ]

28 голосов
/ 14 февраля 2011

Я предлагаю использовать

array ^= numpy.random.rand(len(array)) < prob

Это, пожалуй, самый эффективный способ получения желаемого результата.Он изменит массив на месте, используя «xor» для инвертирования записей, для которых случайное условие оценивается как True.

Почему я могу принять значение массива, но не его отрицание?

Вы также не можете принять значение истинности массива:

>>> bool(array)
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

Оператор not неявно пытается преобразовать свой операнд в bool, а затем возвращаетпротивоположное значение истины.Невозможно перегрузить not для выполнения любого другого поведения.Чтобы отрицать массив NumPy bool с, вы можете использовать

~array

или

numpy.logical_not(array)

или

numpy.invert(array)

, хотя.

3 голосов
/ 14 февраля 2011

putmask очень эффективно, если вы хотите заменить выбранные элементы:

import numpy as np

np.putmask(array, numpy.random.rand(array.shape) < prob, np.logical_not(array))
2 голосов
/ 14 февраля 2011

Возможно , это поможет вам двигаться дальше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...