2017-04-25 62 views
0

在下面的代码片段,我该如何避免计算下面numpy的变量mask,在程序Get_maskGet_K_Shell_Tezbarterorvol?这些变量是大型数组,我必须定义至少六个重用它们的过程。看起来我所做的并不是一个好主意,而且速度很慢。如何避免在此python类中重新计算变量?

import numpy as np 
# this computes various quantities related to the shell in a object oriented way 
class Shell_Data: 
    def __init__(self, data): 
     self.data = data 

    def Get_mask(self): 
      zbar=self.data['z2a1'] 
      y=self.data['y']*1000 
      mask= np.logical_and(zbar >= 16 ,zbar<= 19 ) 
      return self.mask 

    def Get_Shell_Te(self): 
      self.mask =self.Get_mask() 
      te =self.data['te'][self.mask] 
      ro =self.data['ro'][self.mask] 
      rvol =self.data['rvol'][self.mask] 
      self.Shell_Te=np.sum(te*ro/rvol)/(np.sum(ro/rvol)) 
      print "Shell Temperature= %0.3f eV" % (self.Shell_Te) 
      return self.Shell_Te 

    def Get_Shell_ro(self): 
      mask =self.Get_mask() 
      te =self.data['te'][mask] 
      ro =self.data['ro'][mask] 
      rvol =self.data['rvol'][mask] 
      radk =self.data['radk'][mask] 
      self.Shell_ro=np.sum(radk*ro/rvol)/np.sum(radk/rvol) 
      return self.Shell_ro 
+1

如何在'__init__'方法中计算它们并将它们存储在对象中? – JohanL

+0

将简单地在__init__中定义'zbar','ro'和'rvol',使它们可以在'Get_Shell_ro'中访问? – wander95

+0

您需要指定'self.ro'并使用相同的语法访问它们。 – JohanL

回答

0

zbar取决于self.data。如果更新self.data,则可能需要重新计算它。

如果您可以使数据不可变,您可以计算一次这些值,例如,在构造函数中。

如果你想避免计算掩模数据,直到它的实际需要,你可以缓存值,就像这样:

class Shell_Data(...): 

    def __init__(self,...): 
    self.cached_mask = None 
    ... 

    # @property makes an access to self.mask 
    # to actually return the result of a call to self.mask() 
    @property 
    def mask(self): 
    if self.cached_mask is None: # Not yet calculated. 
     self.cached_mask = self.computeMask() 
    return self.cached_mask 

    def computeMask(self): 
    zbar = ... 
    ... 
    return np.logical_and(...) 

    def someComputation(self): 
    # The first access to self.mask will compute it. 
    te = self.data['te'][self.mask] 
    # The second access will just reuse the same result. 
    ro = self.data['ro'][self.mask] 
    ... 

如果你有变异self.data,你可以缓存的计算数据,并重新 - 仅在self.data更改时计算。例如。如果您有setData()方法,您可以重新计算其中的掩码,或者将self.cached_mask设置为None

(此外,阅读关于再次实例变量。

每个方法接收一个名为self的参数,它被称为对象的实例。您可以访问所有的实例变量作为self.东西,正好如果你在一个方法中设置一个实例变量,你可以直接访问另一个实例变量(例如self.mask),不需要返回它。如果你返回一些东西从一种方法来看,它可能不值得存储为一个实例变量,如self.mask。)