Векторизация функции python



У меня есть старая функция с именем old_func, которая принимает в качестве входных данных два позиционных аргумента, x и y. Вход функции был записан следующим образом, используя Кортеж в качестве входа:



def old_func(position):

x, y = position
return x**2 + y**2


Теперь мне нужен быстрый и простой способ вызова функции по сетке значений:



xx = numpy.linspace(0, 1, 100)
yy = numpy.linspace(0, 1, 100)
X, Y = numpy.meshgrid(xx, yy)

array_positions = (X,Y)
old_fun(array_positions)


Цель состоит в том, что каждая операция над x в функции выполняется на всех X и то же самое для y. Я попытался векторизировать функцию с помощью numpy.vectorize но это не работает. Я предпочитаю не изменять функцию, чтобы принимать массивы NumPy, потому что это займет слишком много времени.
739   2  

2 ответов:

Приведенный ниже код делает свое дело и избавляет вас от необходимости создавать array_positions.


Во-первых, используйте ravel чтобы сгладить X и Y в NumPy массивы формы (10000,).

X_flattened = X.ravel()
Y_flattened = Y.ravel()

Затем используйте apply_along_axis чтобы реализовать пользовательскую функцию итеративно вниз по длине этих уплощенных массивов.

float_array = np.apply_along_axis(old_func, 0, (X_flattened, Y_flattened))

Наконец, переформуйте выходной массив в желаемую форму (100, 100).

np.reshape(float_array, (100, 100))

Ваш собственный код должен (и работает) нормально:

def old_fun(position):

    x, y = position 
    z = x**2 + y**2
    return z

xx = numpy.linspace(0,1,100)
yy = numpy.linspace(0,1,100)
X,Y = numpy.meshgrid(xx, yy)

array_positions = (X,Y)
Z = old_fun(array_positions)

Z.shape есть сейчас (100, 100).

В общем случае массивы numpy будут работать с любым стандартным оператором, например + и **. Обратите внимание, что хотя ваш old_fun принимает Кортеж в качестве входных данных, и этот кортеж должен состоять из двух значений, тип этих двух значений может быть любым, если этот тип поддерживает математические операторы. Их поддерживают как стандартные скаляры Python, так и массивы numpy, поэтому код работает нормально.

Заметка о @Juanmanuel's ответ: хотя он также отлично работает, apply_along_axis специально не предназначен для векторизации в том смысле, что люди обычно хотят использовать его, т. е. получать хорошую производительность от numpy. apply_along_axis приведет к медленному циклу Python, а не к быстрому циклу C, Как правильно векторизованный код. Ваш собственный код использует правильную векторизацию, поэтому используйте ее вместо этого.

Comments

    Ничего не найдено.