Ваш вопрос не дает четкого представления о том, какой вывод вы хотели бы видеть из векторизованной функции, но я собираюсь предположить, что вы хотели бы, чтобы один и тот же список (A) применялся в качестве аргумента при каждом вызове f () (т.е. один раз для каждого элемента в массиве X)
Векторизованная версия функции гарантирует, что все аргументы являются массивами, а затем применяет правила широковещания numpy , чтобы определить, как эти аргументы должны комбинироваться.
Как и в случае np.array с обёрткой np.ndarray, приведение аргументов к массивам пытается быть полезным, автоматически преобразовывая список в массив, содержащий те же элементы, а не создавая массив с 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 (), но работает на несколько более низком уровне.