2016-04-22 141 views
3

我試圖寫的statsmodels式API的包裝(這是一個簡化版本,功能確實比這個更多)中調用帕齊時:如果我給這個函數命名空間問題的功能

import statsmodels.formula.api as smf 

def wrapper(formula, data, **kwargs): 
    return smf.logit(formula, data).fit(**kwargs) 

給用戶,誰再試圖定義他/她自己的功能:

def square(x): 
    return x**2 

model = wrapper('y ~ x + square(x)', data=df) 

,他們會得到NameError因爲patsy模塊正在尋找在wrapper的命名空間功能square。有沒有一種安全的,Pythonic的方式來處理這種情況,而不必事先知道函數名稱或需要多少功能?

供參考:這是Python 3.4.3。

+0

我不知道細節(對我來說太過神奇),但是'statsmodels.base.model.Model.from_formula'文檔字符串描述了** kwarg中的'eval_env' kwd,您可能會增加由'from_formula'由所有或大部分模型繼承。 – user333700

+0

是的,我確實嘗試過;似乎沒有工作,但也許我沒有正確地稱呼它。 – chriswhite

+0

您是否嘗試將其設置爲3?在類似的情況下,我正在使用try..except wrappping來計算出用戶函數的深度。 – user333700

回答

2

statsmodels使用patsy包來解析公式並創建設計矩陣。 patsy允許用戶功能作爲公式的一部分,並獲取或評估用戶名稱空間或環境中的用戶功能。

作爲參考看到http://patsy.readthedocs.org/en/latest/API-reference.html

from_formula eval_env關鍵字的模型實現了式接口懦夫的方法。它使用eval_env爲patsy提供必要的信息,默認情況下是用戶的調用環境。這可以被用戶使用相應的關鍵字參數覆蓋。

定義eval_env的最簡單方法是指示patsy應該使用的堆棧級別的整數。 from_formula正在增加它以考慮statsmodels方法中的附加級別。

根據評論,eval_env = 2將使用創建模型的級別中的下一更高級別,例如,與model = smf.logit(..., eval_env=2)

這將創建模型,調用patsy並創建設計矩陣,model.fit()將估計它並返回結果實例。

+0

如果存在多個嵌套的包裝,將其作爲參數並在增加它之後傳遞它是有意義的。例如'def f(...,eval_env = 1):... smf.logit(...,eval_env = eval_env + 1)' –

+0

如果我正確理解您的評論,那麼這就是from_formula所做的,https: //github.com/statsmodels/statsmodels/blob/master/statsmodels/base/model.py#L138 eg如果提供並遞交,則遞增。總體而言,我會在擴大「eval」方法之前檢查安全問題。 – user333700

1

,如果你願意用eval做你的函數的重任,你可以構建從參數的命名空間wrapper和局部變量外框:

wrapper_code = compile("smf.logit(formula, data).fit(**kwargs)", 
         "<WrapperFunction>","eval") 
def wrapper(formula,data,**kwargs): 
    outer_frame = sys._getframe(1) 
    namespace = dict(outer_frame.f_locals) 
    namespace.update(formula=formula, data=data, kwargs=kwargs, smf=smf) 
    return eval(wrapper_code,namespace) 

我真的不因爲它看起來是logit正在做的事情,因爲它引發了一個NameError,並且只要wrapper_code未被修改,並且沒有名稱衝突(如使用名爲data的東西),這應該做你想做的事情。

+0

哦,這是超級有趣,我可以考慮如果這變得更加複雜,往前走。謝謝! – chriswhite

+0

有一個問題,我不知道如何在這種情況下工作,是我們(模型或結果)再次需要相同的信息時,例如用於評估或轉換「預測」中的解釋變量。 patsy保留周圍的信息,並使用一些'eval'魔法,AFAIK。 – user333700