Ускорить двойную петлю в Python

Есть ли способ ускорить двойной цикл, который обновляет его значения из предыдущей итерации?

В коде:

def calc(N, m): x = 1.0 y = 2.0 container = np.zeros((N, 2)) for i in range(N): for j in range(m): x=np.random.gamma(3,1.0/(y*y+4)) y=np.random.normal(1.0/(x+1),1.0/sqrt(x+1)) container[i, 0] = x container[i, 1] = y return container calc(10, 5) 

Как вы можете видеть, внутренний цикл обновляет переменные x и y, а внешний цикл начинается с другого значения x каждый раз. Я не думаю, что это векторизуемо, но, возможно, есть и другие возможные улучшения.

Благодаря!

2 Solutions collect form web for “Ускорить двойную петлю в Python”

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

Гамма-функции имеют свойство масштабирования , так что, если вы нарисуете значение x из распределения гаммы (k, 1), то c*x будет значением, полученным из распределения гамма (k, c). Аналогично, при нормальном распределении вы можете взять значение y полученное из нормального (0, 1), и преобразовать его в значение, полученное из нормального распределения (m, s), выполняющего x*s + m . Таким образом, вы можете переписать свою функцию следующим образом:

 def calc(N, m): x = 1.0 y = 2.0 container = np.zeros((N, 2)) nm = N*m gamma_vals = np.random.gamma(3, 1, size=(nm,)) norm_vals = np.random.normal(0, 1, size=(nm,)) for i in xrange(N): for j in xrange(m): ij = i*j x = gamma_vals[ij] / (y*y+4) y = norm_vals[ij]/np.sqrt(x+1) + 1/(x+1) container[i, 0] = x container[i, 1] = y return container 

Если фактические параметры ваших распределений имели более простое выражение, вы, возможно, сможете использовать какую-то сложную форму np.cumprod или тому подобное и избавить себя от циклов. Я не могу понять, как это сделать …

Это работает?

 for i in xrange(N): # xrange is an iterator, range makes a new list. # You save linear space and `malloc`ing time by doing this x += m*y # a simple algebra hack. Compute this line of the loop just once instead of `m` times y -= m*x y *= -1 # another simple algebra hack. Compute this line of the loop just once instead of `m` times container[i,0] = x container[i,1] = y return container 
  • Нажатие Radix Sort (и python) до его пределов
  • Код Cython Numpy не быстрее, чем чистый питон
  • Как оптимизировать операции над большими (75 000 элементов) наборами логических элементов в Python?
  • Использование лямбда-функций в алгоритме RK4
  • В управляемом коде, как мне достичь хорошей локальности ссылок?
  • sorted () с использованием выражений генератора, а не списков
  • Оптимизация двух SQL-запросов и понимания списка
  • Дискретная оптимизация в python
  • Оптимизация NumPy с Cython
  • Сравнение нескольких файлов csv и поиск совпадений
  • Пакет оптимизатора функций Boolean для Python
  • Python - лучший язык программирования в мире.