У меня есть трехмерный массив формы (2,2,2). Я хотел бы думать об этом как о двумерной матрице с одномерными массивами в качестве записей.
Я хотел бы применить функцию к каждой записи (то есть к каждому 1-мерному массиву) в моей матрице. Я знаю, что могу векторизовать свою функцию, чтобы применить ее к каждому числу в моем массиве. Я также знаю, что могу применить функцию по одной оси. Однако мне не удалось применить функции по двум осям.
Вот мое последнее испытание:
import numpy as np
def sqrtSum(a, b):
return np.sqrt(a+b)
def sqrtSumWrapper(row):
return np.array([sqrtSum(x[0], x[1]) for x in row])
z = np.array([[[1,2],[3,4]],[[5,6],[7,8]]])
np.apply_along_axis(sqrtSumWrapper, 1, z)
В приведенном выше примере моим желаемым результатом был бы массив формы (2,2) с записями ((sqrt (3), sqrt (7)), (sqrt (11), sqrt (15)). Когда я запускаю код выше, я получаю ошибку неверный индекс для скалярной переменной..
Я думаю, что мне не хватает важного аспекта того, как работает apply_along_axis, и я был бы благодарен за ваш вклад в то, как исправить код.
Обновлено: Пока что ответы сосредоточены на изменении входной функции sqrtSum. Эта функция - всего лишь пример. Меня интересует общий ответ для произвольной функции ввода, которая принимает n входных параметров и возвращает скаляр.
Решение: Решение на удивление простое (позор мне, что я его не видел)
import numpy as np
def sqrtSum(a, b):
return np.sqrt(a+b)
def sqrtSumWrapper(x):
return sqrtSum(x[0], x[1])
z = np.array([[[1,2],[3,4]],[[5,6],[7,8]]])
np.apply_along_axis(sqrtSumWrapper, 2, z)
Спасибо всем, кто ответил.
вы можете использовать функции numpy sum и sqrt.
z = np.array([[[1,2],[3,4]],[[5,6],[7,8]]])
s = np.sum(z,axis = 2)
print s.tolist()
# [[3, 7], [11, 15]]
sqrt = np.sqrt(s)
Спасибо. Функции - это просто пример. Как насчет общего ответа для произвольной функции, которая принимает одномерный массив и возвращает скаляр?
Вот как правильно использовать numpy.apply_along_axis
. Применяемая функция должна быть функцией одномерного массива:
def sqrtSum(arr):
return np.sqrt(np.sum(arr))
>>> z = np.array([[[1,2],[3,4]],[[5,6],[7,8]]])
>>> np.apply_along_axis(sqrtSum, 2, z)
array([[1.73205081, 2.64575131],
[3.31662479, 3.87298335]])
Для сравнения:
>>> np.array([[np.sqrt(3), np.sqrt(7)],[np.sqrt(11), np.sqrt(15)]])
array([[1.73205081, 2.64575131],
[3.31662479, 3.87298335]])
Спасибо за ваше решение. Я недостаточно ясно выразился. Функция sqrtSum - это просто простой пример. На практике это может быть намного сложнее (и, возможно, даже мне неизвестно). Итак, как ответить на мой вопрос, если вы считаете детали sqrtSum черным ящиком?
sqrtSum
может быть любой функцией, которая сокращает одномерный массив до скаляра. Какой размер, это зависит от аргумента оси, переданного в apply_along_axis
. Вот как это работает.
Помните, что
apply_along_axis
по-прежнему выполняет итерацию (на уровне Python) по другим измерениям. Это не ускоряет работу. Посмотрите на его код или поищите в SO другие вопросы о функции для получения более подробной информации.