#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. Я немного изменил свой вопрос из-за того, что мой вопрос недостаточно ясен.