Оптимизация нескольких вложенных циклов в python - PullRequest
0 голосов
/ 21 января 2012

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

import time
import numpy as np

a = 1000
b = 500
sum2,sum3,sum4 = 0
t0 = time.time()

x = np.random.random(a*a).reshape([a,a])

for outer1 in xrange(0,a):
    for inner1 in xrange(0,b):
        for outer2 in xrange(0,a):
            for inner2 in xrange(0, a):
                sum2 += x[outer2][inner2]  #this is not the only operation I have   
        for outer3 in xrange(0,a):
            for inner3 in xrange(0, a):
                 sum3 += x[outer3][inner3] #this is not the only operation I have 
        for outer4 in xrange(0,a):
            for inner4 in xrange(0, a):
                sum4 += x[outer4][inner4] #this is not the only operation I have 

print time.time() - t0
print 'sum2: '+str(sum2)+' sum3: '+str(sum3)+' sum4: '+str(sum4)

Я использую Python 2.7.Спасибо.

Ответы [ 2 ]

2 голосов
/ 21 января 2012

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

x = np.random.random(a*a)
sum2 = x.sum()

и т. Д.

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

1 голос
/ 21 января 2012

Как подсказывает ваш код, sum2 зависит только от значений outer2 и inner2, и это делается в двух циклах, чьи переменные outer1 и inner1. В вставленном вами коде вы можете просто пропустить 2 внешних цикла (outer1 и inner1) и вместо этого умножить значение sum2 на a*b. Это устраняет два цикла и заменяет их умножением, которое должно быть быстрее.

Я не знаю, возможно ли это и с вашим реальным кодом, но в опубликованном вами коде это должно быть возможно.

...