Функция, которая принимает сетчатую сетку значений

#python #numpy

#python #numpy

Вопрос:

Мне нужна функция, которая принимает 2 числа и матрицу и выполняет операцию умножения, используя их, а затем суммирует каждый элемент матрицы после умножения (см. Код ниже).

Я пытаюсь выполнить эту операцию для всех возможных комбинаций x и y. Каков наилучший способ сделать это без использования циклов, поскольку я знаю, что мог бы перебирать функцию с разными значениями x и y, но это не кажется эффективным способом сделать это.

Я пытался использовать сетчатую сетку в качестве входных данных, но это не сработало из-за способа трансляции входных данных.

 import numpy as np

def my_func(num1, num2, matrix2):
    return np.sum(matrix*num1*num2)

x = np.linspace(0,5)
y = np.linspace(0,1)

X, Y = np.meshgrid(x, y)
matrix = np.array([[1],[2],[3]])

a = my_func(X,Y,matrix)
 

Я получаю следующую ошибку:

 ValueError: operands could not be broadcast together with shapes (50,50) (3,1)
 

Я хотел a бы получить сетчатую сетку значений, где каждое значение в массиве соответствует выходному значению my_func для каждой возможной комбинации x и y .

Комментарии:

1. Пожалуйста, предоставьте какой-нибудь пример ввода и какой-нибудь пример вывода.

2. @Kraigolas Я добавил результат, который получаю после запуска кода, если вы это имеете в виду.

3. я хочу сказать, приведите несколько примеров того, что вы пытаетесь получить как a . Немного неясно, чего вы пытаетесь достичь.

4. @Kraigolas Я отредактировал свое уравнение, чтобы мою цель было легче понять.

Ответ №1:

Результат x * y * M , когда x и y являются скалярными, справедлив M.shape . Если вы хотите получить этот результат для каждого значения x и y , вам понадобится результат формы x.shape y.shape M.shape . Вы можете сделать это с помощью широковещательной передачи для совершенно общего случая. Идея в том, что вам нужно изменить x форму, чтобы конечные значения тоже заполняли y.ndim M.ndim размеры и y имели M.ndim конечные размеры.

Ради суммирования на самом деле проще использовать ravel M , хотя np.sum с версии 1.7.0 допускается использование нескольких осей.

 def my_func(x, y, matrix):
    x = np.reshape(x, x.shape   (1,) * (y.ndim   1))
    y = np.reshape(y, y.shape   (1,))
    return (x * y * matrix.ravel()).sum(axis=-1)
 

Если вы хотите ввести x и y которые уже транслируются вместе, вы можете немного скорректировать вычисление:

 def my_func(x, y, matrix):
    return ((x * y)[:, None] * matrix.ravel()).sum(-1)
 

Концептуальное различие заключается в том, что первая версия принимает linspace созданные вами массивы напрямую, в то время как вторая версия требует, чтобы вы построили meshgrid или, по крайней мере, транспонировали один из массивов.

Комментарии:

1. Я отредактировал свой вопрос, чтобы было более понятно, какой результат я ищу.

2. @NahPlsMan. Прохладный. Я обновил сумму. Попробуйте запустить то, что я опубликовал, и дайте мне знать, если это сработает.

3. Я запустил код, и он сработал хорошо, спасибо. Однако есть какой-то способ использовать сетки X и Y в качестве входных данных для функции и заставить функцию создавать сетку значений. Я думаю о чем-то похожем на то, что делает np.vectorize, при котором функция принимает каждый аргумент из входного массива и использует его для вычисления возврата.

4. @NahPlsMan. Я добавил версию, которая принимает сетчатую сетку.

Ответ №2:

Похоже, вам нужно настроить размеры вашего x y массива and:

 import numpy as np

def my_func(num1, num2, matrix2):
    return matrix*num1*num2

x = np.linspace(0,5, num=3)
y = np.linspace(0,1, num=3)

X, Y = np.meshgrid(x, y)
matrix = np.array([[1],[2],[3]])

a = my_func(X,Y,matrix)
print(a)
# [[ 0.   0.   0. ]
#  [ 0.   2.5  5. ]
#  [ 0.   7.5 15. ]]
 

Комментарии:

1. Я немного изменил свой вопрос из-за того, что мой вопрос недостаточно ясен.