В вашем вопросе не ясно, какой результат вы хотели бы видеть от векторизованной функции, но я предполагаю, что вы хотели бы, чтобы один и тот же список (A) применялся в качестве аргумента для каждого вызова f() (т.е. один раз для каждого элемента в массиве X)
Векторизованная версия функции гарантирует, что все аргументы являются массивами, а затем применяет numpy. правила вещания, чтобы определить, как эти аргументы должны быть объединены.
Как и в случае с оболочкой np.ndarray np.array, приведение аргументов к массивам пытается быть полезным, автоматически преобразовывая список в массив, содержащий те же элементы, а не создавая массив с dtype=object, который содержит список как его единственный элемент. Большую часть времени это то, что мы хотим, но в вашем случае это «умное» поведение возвращается, чтобы укусить вас.
Хотя может быть способ указать numpy обрабатывать только определенные входные данные как векторы, есть два простых способа получить поведение, которое вам нужно:
- Вручную создайте массив с dtype=object для работы в рамках правил вещания.
- Curry значение перед векторизацией функции
<сильный>1. dtype=объект
Массивы Numpy получают свою эффективность за счет хранения только одного типа элементов, но они все же могут содержать произвольные объекты python, указав, что сохраненный тип данных является объектами python:
list_obj_array = np.ndarray((1,), dtype=object)
list_obj_array[0] = [1,2,3]
f2(X,list_obj_array) # using your definition from above
печатает:
type(A)=<type 'list'>, A=[1, 2, 3]
type(A)=<type 'list'>, A=[1, 2, 3]
type(A)=<type 'list'>, A=[1, 2, 3]
type(A)=<type 'list'>, A=[1, 2, 3]
type(A)=<type 'list'>, A=[1, 2, 3]
type(A)=<type 'list'>, A=[1, 2, 3]
type(A)=<type 'list'>, A=[1, 2, 3]
type(A)=<type 'list'>, A=[1, 2, 3]
type(A)=<type 'list'>, A=[1, 2, 3]
type(A)=<type 'list'>, A=[1, 2, 3]
type(A)=<type 'list'>, A=[1, 2, 3]
и возвращает:
array([ 6. , 5.4 , 4.90909091, 4.5 , 4.15384615,
3.85714286, 3.6 , 3.375 , 3.17647059, 3. ])
<сильный>2. Карри
Поскольку вы передаете один и тот же список вызову функции для каждого элемента в массиве, вы можете сохранить список непосредственно с помощью функции путем каррирования перед применением векторизации:
def curry_f(A):
def f_curried(x):
return f(x, A) # using your definition from above
return f_curried
f2 = np.vectorize(curry_f(P))
f2(X)
печатает:
type(A)=<type 'list'>, A=[1, 2, 3]
type(A)=<type 'list'>, A=[1, 2, 3]
type(A)=<type 'list'>, A=[1, 2, 3]
type(A)=<type 'list'>, A=[1, 2, 3]
type(A)=<type 'list'>, A=[1, 2, 3]
type(A)=<type 'list'>, A=[1, 2, 3]
type(A)=<type 'list'>, A=[1, 2, 3]
type(A)=<type 'list'>, A=[1, 2, 3]
type(A)=<type 'list'>, A=[1, 2, 3]
type(A)=<type 'list'>, A=[1, 2, 3]
и возвращает:
array([ 6. , 5.4 , 4.90909091, 4.5 , 4.15384615,
3.85714286, 3.6 , 3.375 , 3.17647059, 3. ])
P.S. вы также можете взглянуть на np.frompyfunc — он похож на vectorize(), но работает на несколько более низком уровне.
person
Gabriel Grant
schedule
21.12.2010