Есть ли способ получить каждый элемент списка без использования циклов? - PullRequest
2 голосов
/ 05 ноября 2019

Я нашел эту задачу в книге моего профессора:

def f(x):
    return f = log(exp(z))

def problem(M: List)
    return np.array([f(x) for x in M])

Как мне реализовать решение?

1 Ответ

2 голосов
/ 05 ноября 2019

Numpy предназначен для выполнения операций над целыми массивами. Ваш профессор ожидает, что вы будете использовать эту функциональность.

Начните с преобразования вашего списка M в массив z:

z = np.array(M)

Теперь вы можете выполнять поэлементные операции, такие как exp иlog:

e = np.exp(z)
f = 1 + e
g = np.log(f)

Функции np.exp и np.log применяются к каждому элементу массива. Если входные данные не являются массивом, они будут преобразованы в один.

Операции, подобные 1 + e, также работают со всем массивом, в данном случае с использованием магии broadcasting . Поскольку 1 является скаляром, он может быть однозначно расширен до той же формы, что и e, и добавлен, как если бы он был np.add.

Обычно последовательность операций может бытькомпактифицировано в одну строку, аналогично тому, что вы сделали в своей первоначальной попытке. Вы можете немного уменьшить количество операций, используя np.log1p:

def f(x):
    return np.log1p(np.exp(x))

Обратите внимание, что я не преобразовал x в массив первым, поскольку np.exp сделает это дляyou.

Основная проблема этого наивного подхода заключается в том, что np.exp переполнится значениями, которые мы ожидаем получить разумные результаты. Эту проблему можно решить, используя методику этот ответ:

def f(x):
    return np.log1p(np.exp(-np.abs(x))) + np.maximum(x, 0)
...