Как лучше написать функцию, которая может принимать либо скалярные поплавки, либо числовые векторы (1-й массив), и возвращать скалярный, 1-й массив или 2-й массив, в зависимости от ввода?
Функция является дорогостоящей и часто называется, и я не хочу возлагать бремя на вызывающего, чтобы делать специальные приведения к аргументам или возвращать значения. Это нужно только для обработки чисел (не списков или других повторяющихся вещей).
np.vectorize может быть медленным (Передача функции python на массивы numpy) и другие ответы (Получение Python функция, чтобы чисто вернуть скаляр или список, в зависимости от количества аргументов) и np.asarray(Функция python, которая принимает в качестве аргумента скаляр или массив numpy) не помогает в получении размеров, необходимых для выходного массива.
Этот тип кода будет работать в Matlab, Javascript и других языках:
import numpy as np
def func( xa, ya ):
# naively, I thought I could do:
xy = np.zeros( ( len(xa), len(ya) ) )
for j in range(len( ya )):
for i in range(len( xa )):
# do something complicated
xy[i,j] = x[i]+y[j]
return xy
Прекрасно работает для массивов:
x = np.array([1., 2.])
y = np.array([2., 4.])
xy = func(x,y)
print xy
[[ 3. 5.]
[ 4. 6.]]
Но не работает для скалярных поплавков:
x = 1.
y = 3.
xy = func(x,y)
print xy
<ipython-input-64-0f85ad330609> in func(xa, ya)
4 def func( xa, ya ):
5 # naively, I thought I could do:
----> 6 xy = np.zeros( ( len(xa), len(ya) ) )
7 for j in range(len( ya )):
8 for i in range(len( xa )):
TypeError: object of type 'float' has no len()
Использование np.asarray в подобной функции дает:
<ipython-input-63-9ae8e50196e1> in func(x, y)
5 xa = np.asarray( x );
6 ya = np.asarray( y );
----> 7 xy = np.zeros( ( len(xa), len(ya) ) )
8 for j in range(len( ya )):
9 for i in range(len( xa )):
TypeError: len() of unsized object
Каков быстрый, элегантный и питонический подход?