Как перебирать "некоторые" размеры массива numpy?

У меня есть трехмерный массив формы (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)

Спасибо всем, кто ответил.

Помните, что apply_along_axis по-прежнему выполняет итерацию (на уровне Python) по другим измерениям. Это не ускоряет работу. Посмотрите на его код или поищите в SO другие вопросы о функции для получения более подробной информации.

hpaulj 02.05.2018 18:35
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3
1
132
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

вы можете использовать функции 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)

Спасибо. Функции - это просто пример. Как насчет общего ответа для произвольной функции, которая принимает одномерный массив и возвращает скаляр?

whitealex 02.05.2018 10:36
Ответ принят как подходящий

Вот как правильно использовать 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 черным ящиком?

whitealex 02.05.2018 11:33
sqrtSum может быть любой функцией, которая сокращает одномерный массив до скаляра. Какой размер, это зависит от аргумента оси, переданного в apply_along_axis. Вот как это работает.
fferri 02.05.2018 11:35

Другие вопросы по теме