Ответ 1
Используйте numpy.vectorize
для переноса func перед тем, как применить его к массиву x
:
from numpy import vectorize
vfunc = vectorize(func)
y = vfunc(x)
Я использую Matplotlib и Numpy для создания некоторых графиков. Я хочу определить функцию, которая задает массив, возвращает другой массив со значениями, рассчитанными по-разному, например:
def func(x):
return x*10
x = numpy.arrange(-1,1,0.01)
y = func(x)
Это нормально. Теперь, однако, я хочу иметь if-statement внутри 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()
, и они не соответствуют счет за то, что мне нужно. Итак, есть ли хороший способ сделать элемент массива элементов массива мудрым, как в первом примере?
Используйте numpy.vectorize
для переноса func перед тем, как применить его к массиву x
:
from numpy import vectorize
vfunc = vectorize(func)
y = vfunc(x)
Я знаю, что слишком поздно для этого ответа, но я очень рад изучению 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
, так как это работает для маскированных массивов.
Это должно делать то, что вы хотите:
def func(x):
small_indices = x < 10
x[small_indices] = 0
x[invert(small_indices)] *= 10
return x
invert
- это функция Numpy. Обратите внимание, что это изменяет аргумент. Чтобы этого не произошло, вам нужно будет изменить и вернуть copy
x
.
(Я понимаю, что это старый вопрос, но...)
Есть еще один вариант, который здесь не упоминался - использование 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
]
)
Хотя это и не очень хорошо читается, это всего лишь одно выражение (а не серия операторов), и оно не компрометирует примитивную скорость (как np.vectorize
делает np.vectorize
).
x = numpy.arrange(-1,1,0.01)
mask = x>=0
y = numpy.zeros(len(x))
y[mask] = x[mask]*10
mask
- это логический массив, который равен True
- это индексы массива, соответствующие условию, и False
в другом месте. Последняя строка заменяет все значения в исходном массиве на это значение, умноженное на 10.
Отредактировано, чтобы отразить соответствующий комментарий Бьорна
не уверен, зачем тебе нужна функция
x = np.arange(-1, 1, 0.01)
y = x * np.where(x < 0, 0, 10)