Функция Numpy Array с оператором if - PullRequest
17 голосов
/ 07 ноября 2011

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

def func(x):
     return x*10

x = numpy.arrange(-1,1,0.01)
y = func(x)

Это нормально.Теперь, однако, я хочу иметь оператор if внутри func, например:

def func(x):
     if x<0:
          return 0
     else:
          return x*10

x = numpy.arrange(-1,1,0.01)
y = func(x)

Это, к сожалению, приводит к следующей ошибке

Traceback (most recent call last):
  File "D:\Scripts\test.py", line 17, in <module>
    y = func(x)
  File "D:\Scripts\test.py", line 11, in func
    if x<0:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

Я посмотрел документацию для all() и any() и они не отвечают всем требованиям за то, что мне нужно.Так есть ли хороший способ сделать функцию обрабатывать массивы по элементам, как в первом примере?

Ответы [ 6 ]

13 голосов
/ 07 ноября 2011

Используйте numpy.vectorize, чтобы обернуть func перед применением к массиву x:

from numpy import vectorize
vfunc = vectorize(func)
y = vfunc(x)
12 голосов
/ 11 ноября 2015

Я знаю, что уже слишком поздно для этого ответа, но я взволнован, изучая NumPy.Вы можете векторизовать функцию самостоятельно с помощью numpy.where.

def func(x):
    import numpy as np
    x = np.where(x<0, 0., x*10)
    return x   

Примеры

Использование скаляра в качестве ввода данных:

x = 10
y = func(10)
y = array(100.0)

использование массива в качестве ввода данных:

x = np.arange(-1,1,0.1)
y = func(x)
y = array([ -1.00000000e+00,  -9.00000000e-01,  -8.00000000e-01,
    -7.00000000e-01,  -6.00000000e-01,  -5.00000000e-01,
    -4.00000000e-01,  -3.00000000e-01,  -2.00000000e-01,
    -1.00000000e-01,  -2.22044605e-16,   1.00000000e-01,
     2.00000000e-01,   3.00000000e-01,   4.00000000e-01,
     5.00000000e-01,   6.00000000e-01,   7.00000000e-01,
     8.00000000e-01,   9.00000000e-01])

Предостережения :

1) Если x является замаскированным массивом, вам нужно использовать np.ma.where вместо, поскольку это работает для замаскированных массивов.

10 голосов
/ 07 ноября 2011

Это должно делать то, что вы хотите:

def func(x):
    small_indices = x < 10
    x[small_indices] = 0
    x[invert(small_indices)] *= 10
    return x

invert - функция Numpy.Обратите внимание, что это изменяет аргумент.Чтобы предотвратить это, вам нужно изменить и вернуть copy из x.

5 голосов
/ 24 августа 2014

(я понимаю, что это старый вопрос, но ...)

Есть еще одна опция, которая не была упомянута здесь - использование np.choose.

np.choose(
    # the boolean condition
    x < 0,
    [
        # index 0: value if condition is False
        10 * x,
        # index 1: value if condition is True
        0
    ]
)

Несмотря на то, что это не очень хорошо читается, это всего лишь одно выражение (а не серия утверждений), и оно не компрометирует присущую numpy скорость (как это делает np.vectorize).

1 голос
/ 07 ноября 2011
x = numpy.arrange(-1,1,0.01)
mask = x>=0
y = numpy.zeros(len(x))
y[mask] = x[mask]*10

mask является логическим массивом, равным True являются индексы массива, соответствующие условию, и False в другом месте. Последняя строка заменяет все значения в исходном массиве на это значение, умноженное на 10.

Отредактировано, чтобы отразить соответствующий комментарий Бьорна

0 голосов
/ 21 июня 2019

не уверен, зачем вам нужна функция

x = np.arange(-1, 1, 0.01)
y = x * np.where(x < 0, 0, 10)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...