Создание массива numpy из повторения функции n раз со случайным поведением внутри функции без циклов for

#python #numpy #for-loop #optimization #random

#python #numpy #for-цикл #оптимизация #Случайный

Вопрос:

Я выполняю оптимизацию в своем коде и хотел бы удалить этот цикл for, если это возможно. У меня есть следующий код:

     def f(x):
        return np.pi * x * np.cos((np.pi / 2) * x ** 2)

    def monte_carlo(b, n):
        xrand = np.random.uniform(0, b, (1, n))
        integral = np.sum(f(xrand))
        return b/n * integral

    data = np.array([monte_carlo(b, n) for _ in range(100)])
 

В этом коде b — верхний предел (обычно от 0 до 16), а n — количество используемых выборок (обычно от 10E4 до 10E7). Функция монте-Карло используется для базового интегрирования по методу Монте-Карло интеграла от 0 до b функции f(x).

Что я пытаюсь сделать, так это удалить цикл for в data. Я знаю, что на самом деле это не проблема с производительностью, но мое задание просит попытаться оптимизировать производительность. Прямо сейчас я использую понимание, которое немного быстрее, чем обычный цикл for, но я думаю, что можно сделать больше оптимизации, циклы python for довольно медленные, поэтому я пытаюсь сначала избавиться от них.

Я рассматривал такие функции, как numpy.repeat и numpy.tile, но они не работают, поскольку функция запускается только один раз, а затем продолжает повторять этот результат функции. Я также посмотрел на numpy.fromfunction , но, похоже, я не могу заставить это работать и не думаю, что смогу это использовать. В документации по numpy.fromfunction говорится: «Создайте массив, выполнив функцию по каждой координате». Я не думаю, что это особенно полезно, поскольку аргументы для функций остаются неизменными. Именно случайный элемент внутри функции создает разницу в каждой итерации.

Если кто-нибудь знает, как я могу это решить, это было бы очень ценно, или у него есть другая функция numpy, которую я не нашел во время поиска в Google, которая делает то, что мне нужно. Заранее спасибо!

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

1. Все эти вещи по-прежнему запускают эту функцию много раз. Время выполнения функции является основным потребителем времени, а не механизмом итерации.

2. Да, но удаление цикла for также обычно означает массовое вычисление, что намного быстрее. Для моего случая использования продолжительность выполнения функции, в которой это используется, увеличилась с 80 секунд до примерно 2,5 секунд, реализующих решение sai.

Ответ №1:

В принципе, вы можете выполнить все 100 итераций или сколько угодно за один выстрел. Смотрите код ниже-

 def f(x):
    return np.pi * x * np.cos((np.pi / 2) * x ** 2)


def monte_carlo(b, n, N):
    xrand = np.random.uniform(0, b, (N, n))
    integral = np.sum(f(xrand), axis=1)
    return b / n * integral


# data = np.array([monte_carlo(b, n) for _ in range(100)])
data = monte_carlo(b, n, 100).T