我在尝试定义自己的类时遇到两个问题。首先,最基本的问题是,如果我编写python脚本并尝试将其导入第二个脚本,则导入失败(脚本位于同一目录中)。例如,我写了一个名为first.py的脚本:
def foo(): print("foo")
如果我尝试将其导入第二个脚本,我会'找不到模块'
import first
first.foo()
ImportError: No module named first
其次,我编写了一个脚本,用于定义非线性回归的类。该脚本导入类中的模块。但是,我也需要导入类的OUTSIDE模块。如果未在类定义的内部和外部导入模块,则脚本将不起作用:
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
这些问题是相关的,因为我尝试将此类导入另一个脚本而我不能(如第一个问题)。谁能告诉我发生了什么事?
更新
我刚开始能够导入脚本。无论开始路径上什么样的时髦清洁似乎最终都被删除了。不知道那是什么。但是,我仍然不明白为什么,如果我在我的类定义中导入必要的模块,我必须在我的其他脚本中导入它们。在我看来,如果我的类导入模块,我也不需要全局导入它们。这是对的吗?
答案 0 :(得分:1)
我认为zhangxaochen的第一个评论是问题编号1的最佳起始位置.sys.path应包含python在尝试导入模块时搜索的所有路径。这些是我要解决这个问题的步骤:
确保os.getcwd()返回与os.path.dirname相同的目录(sys.argv [0])
接下来,我确保该路径位于sys.path列表中。
如果两者都结账......