优化嵌套Python for循环?

时间:2017-01-12 23:15:32

标签: python numpy for-loop optimization nested

我在优化以下for循环方面遇到了一些麻烦。我已经查看了map函数,理解表达式以及一些itertools和generator,但我不确定如何对嵌套循环进行优化。非常感谢任何帮助或建议。提前谢谢!

请注意,对象架构是:

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

循环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

循环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 个答案:

答案 0 :(得分:1)

使用numpy标记我假设'optimize'意味着将这些循环转换为已编译的numpy数组表达式。我不认为没有先将所有数据收集为numpy数组,这将需要相同的循环。

您有n variables的列表。每个变量都有一个?参数列表。每个参数都有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已经是一个二维数组,其大小与index1sindex2s中的值范围兼容。

鉴于这些1和2d数组,我们应该能够使用整数组运算派生mat1mat2。如果?相对于m较小且index1index2中的值范围较小,则可能值得这样做。我对你的数据没有真实的感觉。

===========

你提到the map function, comprehension expressions, and a bit of itertools and generators。这些可以使代码看起来更清晰,但速度没有太大差异。

我展示了列表推导的使用。这些表达可以更复杂,但通常以可读性为代价。我喜欢编写辅助函数来隐藏细节。生成器理解可以替换为另一个提供的列表理解。地图涵盖相同的功能。

由于variablesparameters具有属性,我假设您已在类中定义它们。您可以编写将这些属性提取为简单列表或数组的方法。

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]

你甚至可以在没有类结构的情况下编写这些辅助函数。

这不会加速任何事情;它只是隐藏了对象中的一些细节。