Accessing a variable of one method inside another method in the same class – Python

huangapple go评论81阅读模式
英文:

Accessing a variable of one method inside another method in the same class - Python

问题

以下是代码部分的中文翻译:

class MandM:
     def __init__(self, data, X=2, y=2):
        self.data = data
        self.X = X
        self.y = y
           
    def _ols(self):
        y = self.data.iloc[:, :y]
        X = self.data.iloc[:, X:]
        B = pd.DataFrame(inv(np.dot(X.T, X)) @ np.dot(X.T, y))
        B.columns = list(y.columns)
        B.index = list(X.columns)
        yhat = X @ B

        return {"B": B, "yhat": yhat, "y": y, "X": X}
        
    def _sscp(self):
        # 调用ols方法
        ols = MandM(self.data)._ols()
        
        ybar = pd.DataFrame([ols["y"].mean()] * ols["y"].shape[0]) 
        y_ybar = ols["y"] - ybar   
        sscp_tot = pd.DataFrame(np.dot(y_ybar.T, y_ybar))
        sscp_tot.columns = list(ols["y"].columns)
        sscp_tot.index = list(ols["y"].columns)
        
        yhat_ybar = ols["yhat"] - ybar
        sscp_reg = pd.DataFrame(np.dot(yhat_ybar.T, yhat_ybar))
        sscp_reg.columns = list(ols["y"].columns)
        sscp_reg.index = list(ols["y"].columns)
        
        resid = ols["y"] - ols["X"] @ ols["B"]
        y_yhat = ols["y"] - ols["yhat"]
        sscp_resid = pd.DataFrame(np.dot(y_yhat.T, y_yhat))
        sscp_resid.columns = list(ols["y"].columns)
        sscp_resid.index = list(ols["y"].columns)
        
        return {"sscp_tot": sscp_tot, "sscp_reg": sscp_reg, 
                "resid": resid, "sscp_resid": sscp_resid}
英文:

Let's say I have class, MandM, as indicated below with different methods. I want all the variables in each method to be accessible to all other methods in the class because I may need them in other methods.

So what I am doing is like in the example below, where I call a method within another method and then access the variables I want from that method. For each method, I return its output as a dictionary and then I can refer to that variable by name in another method.

My question is, is there another more efficient way to go about this?

class MandM:
     def __init__(self, data, X=2, y=2):
        self.data = data
        self.X = X
        self.y = y
           
    def _ols(self):
        y = self.data.iloc[:, :y]
        X = self.data.iloc[:, X:]
        B = pd.DataFrame(inv(np.dot(X.T, X)) @ np.dot(X.T, y))
        B.columns = list(y.columns)
        B.index = list(X.columns)
        yhat = X @ B

        return {"B": B, "yhat": yhat, "y": y, "X": X}
        
    def _sscp(self):
        # call ols method
        ols = MandM(self.data)._ols()
        
        ybar = pd.DataFrame([ols["y"].mean()] * ols["y"].shape[0]) 
        y_ybar = ols["y"] - ybar   
        sscp_tot = pd.DataFrame(np.dot(y_ybar.T, y_ybar))
        sscp_tot.columns = list(ols["y"].columns)
        sscp_tot.index = list(ols["y"].columns)
        
        yhat_ybar = ols["yhat"] - ybar
        sscp_reg = pd.DataFrame(np.dot(yhat_ybar.T, yhat_ybar))
        sscp_reg.columns = list(ols["y"].columns)
        sscp_reg.index = list(ols["y"].columns)
        
        resid = ols["y"] - ols["X"] @ ols["B"]
        y_yhat = ols["y"] - ols["yhat"]
        sscp_resid = pd.DataFrame(np.dot(y_yhat.T, y_yhat))
        sscp_resid.columns = list(ols["y"].columns)
        sscp_resid.index = list(ols["y"].columns)
        
        return {"sscp_tot": sscp_tot, "sscp_reg": sscp_reg, 
                "resid": resid, "sscp_resid": sscp_resid}

答案1

得分: 3

你可以在__init__方法中创建所有内容,并将它们设置为实例变量,例如self.Bself.ywhat等等。

但如果你更喜欢按需加载它们(惰性加载),可以使用类似这样的属性:

class MandM:
    def __init__(self, data, x=2, y=2):
        self.data = data
        self.x = x
        self.y = y
        self._xvalues = None
        self._yvalues = None
        self._b = None
        self._ywhat = None

    @property
    def xvalues(self):
        if self._xvalues is None:
            self._xvalues = self.data.iloc[:, :self.x]
        return self._xvalues

    @property
    def yvalues(self):
        if self._yvalues is None:
            self._yvalues = self.data.iloc[:, :self.y]
        return self._yvalues

    @property
    def ywhat(self):
        if self._ywhat is None:
            self._ywhat = X @ self.b
        return self._ywhat

    @property
    def b(self):
        if self._b is None:
            B = pd.DataFrame(inv(np.dot(self.xvalues.T, self.xvalues)) @ np.dot(self.xvalues.T, self.yvalues))
            B.columns = list(self.yvalues.columns)
            B.index = list(self.xvalues.columns)
            self._b = B
        return self._b

你还可以编写计算多个值并将它们设置为实例变量的方法,这样你可以在其他方法中重复使用它们:

def _sscp(self):
    ybar = pd.DataFrame([self.yvalues.mean()] * self.yvalues.shape[0])
    y_ybar = self.yvalues - ybar
    sscp_tot = pd.DataFrame(np.dot(y_ybar.T, y_ybar))
    sscp_tot.columns = list(self.yvalues.columns)
    sscp_tot.index = list(self.yvalues.columns)

    yhat_ybar = self.ywhat - ybar
    sscp_reg = pd.DataFrame(np.dot(yhat_ybar.T, yhat_ybar))
    sscp_reg.columns = list(self.yvalues.columns)
    sscp_reg.index = list(self.yvalues.columns)

    resid = self.yvalues - self.xvalues @ self.b
    y_yhat = self.yvalues - self.ywhat
    sscp_resid = pd.DataFrame(np.dot(y_yhat.T, y_yhat))
    sscp_resid.columns = list(self.yvalues.columns)
    sscp_resid.index = list(self.yvalues.columns)

    self.sscp_tot = sscp_tot
    self.sscp_reg = sscp_reg
    self.resid = resid
    self.sscp_resid = sscp_resid

希望这有帮助!

英文:

You could just created everything in the __init__ method and set them as instance variable self.B, self.ywhat, ...

But if you prefer loading them on-demande (lazily), use properties like that :

class MandM:
    def __init__(self, data, x=2, y=2):
        self.data = data
        self.x = x
        self.y = y
        self._xvalues = None
        self._yvalues = None
        self._b = None
        self._ywhat = None

    @property
    def xvalues(self):
        if self._xvalues is None:
            self._xvalues = self.data.iloc[:, :self.x]
        return self._xvalues

    @property
    def yvalues(self):
        if self._yvalues is None:
            self._yvalues = self.data.iloc[:, :self.y]
        return self._yvalues

    @property
    def ywhat(self):
        if self._ywhat is None:
            self._ywhat = X @ self.b
        return self._ywhat

    @property
    def b(self):
        if self._b is None:
            B = pd.DataFrame(inv(np.dot(self.xvalues.T, self.xvalues)) @ np.dot(self.xvalues.T, self.yvalues))
            B.columns = list(self.yvalues.columns)
            B.index = list(self.xvalues.columns)
            self._b = B
        return self._b

You can also have methods that compute multiple values and set them as instance variable, so you can reuse them in other methods

def _sscp(self):
    ybar = pd.DataFrame([self.yvalues.mean()] * self.yvalues.shape[0])
    y_ybar = self.yvalues - ybar
    sscp_tot = pd.DataFrame(np.dot(y_ybar.T, y_ybar))
    sscp_tot.columns = list(self.yvalues.columns)
    sscp_tot.index = list(self.yvalues.columns)

    yhat_ybar = self.ywhat - ybar
    sscp_reg = pd.DataFrame(np.dot(yhat_ybar.T, yhat_ybar))
    sscp_reg.columns = list(self.yvalues.columns)
    sscp_reg.index = list(self.yvalues.columns)

    resid = self.yvalues - self.xvalues @ self.b
    y_yhat = self.yvalues - self.ywhat
    sscp_resid = pd.DataFrame(np.dot(y_yhat.T, y_yhat))
    sscp_resid.columns = list(self.yvalues.columns)
    sscp_resid.index = list(self.yvalues.columns)

    self.sscp_tot = sscp_tot
    self.sscp_reg = sscp_reg
    self.resid = resid
    self.sscp_resid = sscp_resid

huangapple
  • 本文由 发表于 2023年5月21日 20:46:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/76299972.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定