2014-01-15 174 views
0

我在試圖定義我自己的類時遇到了兩個問題。首先,最基本的問題是,如果我編寫python腳本並嘗試將其導入第二個腳本,導入失敗(腳本位於同一目錄中)。例如,我寫了一個腳本調用first.py:在Python腳本中導入模塊

def foo(): print("foo") 

如果我嘗試導入到第二個腳本,我得到

import first 

first.foo() 

ImportError: No module named first 

二「沒有找到模塊」,我寫了一個腳本爲非線性迴歸定義了一個類。該腳本導入類中的模塊。但是,我還需要將該模塊導入到課程外部。如果模塊沒有內外類定義的導入的腳本將無法工作:

class NLS: 
    ''' This provides a wrapper for scipy.optimize.leastsq to get the relevant output for nonlinear least squares. 
    Although scipy provides curve_fit for that reason, curve_fit only returns parameter estimates and covariances. 
    This wrapper returns numerous statistics and diagnostics''' 
    # IMPORT THE MODULES THE FIRST TIME - WILL NOT RUN WITHOUT THESE 
    import numpy as np 
    from scipy.optimize import leastsq 
    import scipy.stats as spst 


    def __init__(self, func, p0, xdata, ydata): 

     # Check the data 
     if len(xdata) != len(ydata): 
      msg = 'The number of observations does not match the number of rows for the predictors' 
      raise ValueError(msg) 

     # Check parameter estimates 
     if type(p0) != dict: 
      msg = "Initial parameter estimates (p0) must be a dictionry of form p0={'a':1, 'b':2, etc}" 
      raise ValueError(msg) 

     self.func = func 
     self.inits = p0.values() 
     self.xdata = xdata 
     self.ydata = ydata 
     self.nobs = len(ydata) 
     self.nparm= len(self.inits) 

     self.parmNames = p0.keys() 

     for i in range(len(self.parmNames)): 
      if len(self.parmNames[i]) > 5: 
       self.parmNames[i] = self.parmNames[i][0:4] 

     # Run the model 
     self.mod1 = leastsq(self.func, self.inits, args = (self.xdata, self.ydata), full_output=1) 

     # Get the parameters 
     self.parmEsts = np.round(self.mod1[0], 4) 

     # Get the Error variance and standard deviation 
     self.RSS = np.sum(self.mod1[2]['fvec']**2) 
     self.df = self.nobs - self.nparm 
     self.MSE = self.RSS/self.df 
     self.RMSE = np.sqrt(self.MSE) 

     # Get the covariance matrix 
     self.cov = self.MSE * self.mod1[1] 

     # Get parameter standard errors 
     self.parmSE = np.diag(np.sqrt(self.cov)) 

     # Calculate the t-values 
     self.tvals = self.parmEsts/self.parmSE 

     # Get p-values 
     self.pvals = (1 - spst.t.cdf(np.abs(self.tvals), self.df))*2 

     # Get biased variance (MLE) and calculate log-likehood 
     self.s2b = self.RSS/self.nobs 
     self.logLik = -self.nobs/2 * np.log(2*np.pi) - self.nobs/2 * np.log(self.s2b) - 1/(2*self.s2b) * self.RSS 

     del(self.mod1) 
     del(self.s2b) 
     del(self.inits)   

    # Get AIC. Add 1 to the df to account for estimation of standard error 
    def AIC(self, k=2): 
     return -2*self.logLik + k*(self.nparm + 1) 

    del(np) 
    del(leastsq) 

    # Print the summary 
    def summary(self): 
     print 
     print 'Non-linear least squares' 
     print 'Model: ' + self.func.func_name 
     print 'Parameters:' 
     print "    Estimate  Std. Error  t-value  P(>|t|)" 
     for i in range(len(self.parmNames)): 
      print "% -5s   % 5.4f  % 5.4f   % 5.4f  % 5.4f" % tuple([self.parmNames[i], self.parmEsts[i], self.parmSE[i], self.tvals[i], self.pvals[i]])     
     print 
     print 'Residual Standard Error: % 5.4f' % self.RMSE 
     print 'Df: %i' % self.df 


## EXAMPLE USAGE 
import pandas as pd 
# IMPORT THE MODULES A SECOND TIME. WILL NOT RUN WITHOUT THESE 
import numpy as np 
from scipy.optimize import leastsq 
import scipy.stats as spst 

# Import data into dataframe 
respData = pd.read_csv('/Users/Nate/Documents/FIU/Research/MTE_Urchins/Data/respiration.csv') 

# Standardize to 24 h 
respData['respDaily'] = respData['C_Resp_Mass'] * 24 

# Create the Arrhenius temperature 
respData['Ar'] = -1/(8.617 * 10**-5 * (respData['Temp']+273)) 

# Define the likelihood null model 
def nullMod(params, mass, yObs): 
    a = params[0] 
    c = params[1]  
    yHat = a*mass**c 
    err = yObs - yHat 
    return(err) 


p0 = {'a':1, 'b':1} 

tMod = NLS(nullMod, p0, respData['UrchinMass'], respData['respDaily']) 

tMod.summary() 

tMod.AIC() 

tMod.logLik 

,因爲我嘗試導入這個類到另一個劇本,我不能將這些問題都涉及(如在第一個問題)。誰能告訴我發生了什麼事?

更新

我剛開始能夠導入腳本。無論在開始的道路上那種時髦的清潔似乎最終都被刪除了。不知道那是什麼。但是,我仍然不明白爲什麼,如果我在我的類定義中導入必要的模塊,我也必須將它們導入到其他腳本中。在我看來,如果我的課程導入模塊,我不應該在全局導入它們。它是否正確?

+2

是'first.py'在同一文件夾與您當前的腳本或它在'sys.path'列表路徑? – zhangxaochen

+0

如果你只*在類定義之前在腳本的頂部導入'numpy'和'scipy'會怎麼樣?另外,爲什麼你有'del(np)'和'del(leastsq)'語句;這似乎很奇怪。 – Evert

+0

至於你的問題的第一部分:這對我來說很好。你所展示的那些代碼實際上是測試腳本中唯一的代碼行? – Evert

回答

1

我認爲來自zhangxaochen的第一條評論是問題編號爲1的最佳開始位置。sys.path應該包含python在您嘗試導入模塊時搜索的所有路徑。這些步驟我會去通過解決這一個:

確保os.getcwd()返回相同的目錄os.path.dirname(sys.argv中[0])

下一頁我」 d確保該路徑位於sys.path列表中。

如果這兩個檢查....

+0

確定我嘗試了第一個診斷,確保os.getswd()與os.path.dirname()是相同的目錄。不是。 os.getcwd()返回:/ Users/Nate/Desktop,而os.path.dirname(sys.argv [0])返回:/ private/var/folders/zl/yxc7hlld61b6y2n5ghnn_q4h0000gn/T /啓動時清理。世界上第二個文件夾是什麼?第一個是(兩個)腳本的目錄。當我嘗試sys.path時,第二個奇怪的文件路徑在列表中,但我的桌面不是。 – Nate

+0

@Nate好吧,那很奇怪。你可以檢查你的終端cmdline下面的命令:'哪個python'然後'ls -l \'哪個python \''?它會覺得你正在運行的Python有一個符號鏈接到一些非常奇怪的文件。順便說一句,'sys.path'可能包含一個空字符串''''作爲第一個元素,它表示您的當前目錄,即Desktop。所以如果沒有列出桌面,它可能仍然存在。 – Evert

+0

真的很奇怪!不知道你爲什麼把它當作你的sys.argv [0]。你是從IDE還是在命令行上運行腳本?當你打印目錄列表中的sys.path是/ Users/Nate/Desktop?如果不是,那麼添加它然後嘗試導入。 – Lafleur