2017-01-12 5 views
0

У меня возникли проблемы с оптимизацией следующих циклов. Я рассмотрел функцию карты, выражения понимания и немного itertools и генераторов, но я не уверен, как подойти к оптимизации для вложенных циклов. Любая помощь или предложения очень приветствуются. Заранее спасибо!Оптимизация вложенного Python для циклов?

Обратите внимание, что объект архитектуры является:

self.variables.parameters.index1/index2/value 
self.variables.rate 
self.state.num 

Loop 1:

mat1 = np.zeros(m, n) 
for idx, variable in enumerate(self.variables): 
    for parameter in variable.parameters: 
     tracking_idx = parameter.index1 + parameter.index2 
     mat1[tracking_idx, idx] = parameter.value 

Loop 2:

mat2 = [] 
for variable in self.variables: 
    rate = variable.rate 
    for parameter in variable.parameters: 
     if parameter.value < 0 and self.state.num[parameter.index1, parameter.index2] <= 0: 
      rate = 0 
    mat2.append(rate) 
+1

Для второго цикла, если у вас есть большое количество параметров, добавление перерыва после инструкции rate = 0 может помочь, поскольку оно останавливает проверку других параметров –

ответ

1

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

У вас есть список nvariables. Каждая переменная имеет список параметров ?. Каждый параметр имеет 3 или 4 атрибута.

Так

rates = np.array([v.rate for v in variables]) 
values = np.array([[p.value for p in v.parameters] for v in variables] 
index1s = <dito> (?,n) array 
index2s = <dita> (?,n) array 

self.state.num уже 2d массив, размер соответствует диапазону значений в index1s и index2s.

Учитывая эти 1 и 2d массивы, мы можем получить mat1 и mat2 с целыми массивами. Если ? мал относительно m и диапазон значений в index1 и index2, то это может стоить того. У меня нет реалистичного восприятия ваших данных.

===========

Вы упоминаете the map function, comprehension expressions, and a bit of itertools and generators. Они могут сделать код немного чище, но не имеют большого значения в скорости.

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

С variables и parameters есть атрибуты Предполагаю, что вы определили их в классах. Вы можете писать методы, которые извлекают эти атрибуты как простые списки или массивы.

class Variable(....): 
    .... 
    def get_values(self): 
     return [p.value for p in self.parameters] 
    def get_rate(self, state): 
     rate = self.rate 
     for parameter in self.parameters: 
      if parameter.value < 0 and     
       state.num[parameter.index1, parameter.index2] <= 0: 
      rate = 0 
     return rate 

values = [v.get_values() for v in variables] 
rates = [v.get_rate(self.state) for v in variables] 

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

Это не ускоряет ничего; он просто скрывает некоторые детали в объекте.

+0

Спасибо! Я использовал представление списка для mat1 и сохранил цикл for для mat2. Это сократило время работы на 20% или около того! – tooty44

Смежные вопросы