2015-09-18 77 views
5

我想使用熊貓和statsmodels擬合數據框子集上的線性模型並返回預測值。但是,我很難找出適合使用的正確的熊貓成語。這裏是我想要做的事:熊貓可以將DataFrame轉換爲Series嗎?

import pandas as pd 
import statsmodels.formula.api as sm 
import seaborn as sns 

tips = sns.load_dataset("tips") 
def fit_predict(df): 
    m = sm.ols("tip ~ total_bill", df).fit() 
    return pd.Series(m.predict(df), index=df.index) 
tips["predicted_tip"] = tips.groupby("day").transform(fit_predict) 

這引起以下錯誤:

--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
<ipython-input-139-b3d2575e2def> in <module>() 
----> 1 tips["predicted_tip"] = tips.groupby("day").transform(fit_predict) 

/Users/mwaskom/anaconda/lib/python2.7/site-packages/pandas/core/groupby.pyc in transform(self, func, *args, **kwargs) 
    3033      return self._transform_general(func, *args, **kwargs) 
    3034   except: 
-> 3035    return self._transform_general(func, *args, **kwargs) 
    3036 
    3037   # a reduction transform 

/Users/mwaskom/anaconda/lib/python2.7/site-packages/pandas/core/groupby.pyc in _transform_general(self, func, *args, **kwargs) 
    2988      group.T.values[:] = res 
    2989     else: 
-> 2990      group.values[:] = res 
    2991 
    2992     applied.append(group) 

ValueError: could not broadcast input array from shape (62) into shape (62,6) 

該錯誤是有道理的,我認爲.transform想要一個數據幀映射到數據幀。但是有沒有辦法在DataFrame上執行groupby操作,將每個塊傳遞給一個函數,將其減少爲一個Series(具有相同的索引),然後將所得到的Series組合成可以插入原始數據框的東西?

回答

2

這裏的頂部部分是相同的,我只是使用玩具數據集b/c我在防火牆後面。

tips = pd.DataFrame({ 'day':list('MMMFFF'), 'tip':range(6), 
         'total_bill':[10,40,20,80,50,40] }) 

def fit_predict(df): 
    m = sm.ols("tip ~ total_bill", df).fit() 
    return pd.Series(m.predict(df), index=df.index) 

如果你改變了「轉換」到「應用」,你會得到:

tips.groupby("day").apply(fit_predict) 

day 
F 3 2.923077 
    4 4.307692 
    5 4.769231 
M 0 0.714286 
    1 1.357143 
    2 0.928571 

這似乎不太你想要什麼,但如果你把水平= 0,你可以根據需要進行:

tips['predicted'] = tips.groupby("day").apply(fit_predict).reset_index(level=0,drop=True) 

    day tip total_bill predicted 
0 M 0   10 0.714286 
1 M 1   40 1.357143 
2 M 2   20 0.928571 
3 F 3   80 2.923077 
4 F 4   50 4.307692 
5 F 5   40 4.769231 
+1

有趣的是,這不適用於seaborn tips數據集,因爲涉及'day'是一個分類對象的錯誤。我想知道這是否是熊貓中的一個錯誤。 – mwaskom

+0

熊貓大師作品。 Categoricals沒有連接/連接標誌的錯誤。 – TomAugspurger

+0

很酷。 @TomAugspurger,你會說這是在熊貓中做到這一點最習慣的方式嗎?如果是的話,我會標記正確的。 – mwaskom

0

編輯:

q.gps.apply(lambda df: df.join(q.fit_predict(df)))

我不得不修改您的fit_predict功能來命名Series

def fit_predict(df): 
m = sm.ols("tip ~ total_bill", df).fit() 
s = pd.Series(m.predict(df), index=df.index) 
s.name = 'Prediction' #EDIT 
return s 
+0

但是,您會注意到,它不適用於問題中給出的示例。 – mwaskom

+0

它不相關,因爲'.describe'將DataFrame映射到DataFrame而不是DataFrame映射到'Series'。 – mwaskom

+0

你是對的。我修改了我的答案,將DataFrame傳遞給DataFrame函數以「轉換」。 –