Поэтому мне было интересно, возможно ли векторизовать понимание списка.
np.vectorize
преобразует функцию в функцию, которая принимает массивы в качестве входных данных. Затем вы можете использовать его вместо понимания списка.
Но он не «векторизует» операцию с точки зрения производительности. На самом деле, он часто медленнее и используется для тестирования или для корректировки синтаксиса.
Кроме того, что означает «объект не подлежит вызову»?
В Python, «вызываемый» - это объект, который можно использовать «как функцию». Конечно, функции могут быть вызваны. Вы можете добавить метод __call__
к другим объектам.
Ниже приведен пример класса, который имеет метод __call__
.
In [33]: class myclass():
...: def __init__(self):
...: pass
...: def __call__(self, x):
...: return x**2
...:
...:
In [34]: A = myclass()
In [35]: A(10)
Out[35]: 100
[x/(x+1) for x in a]
- это выражение, это возвращает значение и не может быть вызван. Аргумент np.vectorize
должен быть вызываемым.
Другие здесь предлагают использовать np.vectorize(lambda x: x/(1+x))
или
def f(x):
return x/(1+x)
f_vec = np.vectorize(f)
Первый - это «лямбда-функция», второй - обычные функции. Оба могут быть вызваны.
Для случая, который вы показываете, вы действительно можете сделать
y = x/(1+x)
, и для этого будут использоваться операции NumPy. Поскольку x является массивом, это считается формой векторизации (вычисления будут выполняться в оптимизированном и векторизованном коде C ++).
Для более сложных вычислений ищите Cython, numbersxpr или Numba.