2015-09-18 23 views
5

Tôi muốn sử dụng gấu trúc và mô hình thống kê để phù hợp với mô hình tuyến tính trên tập hợp con của một khung dữ liệu và trả về giá trị được dự đoán. Tuy nhiên, tôi đang gặp khó khăn trong việc tìm ra thành ngữ gấu trúc phù hợp để sử dụng. Dưới đây là những gì tôi đang cố gắng để làm:Nhóm gấu trúc có thể chuyển đổi một DataFrame thành một Series không?

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) 

Điều này đặt ra các lỗi sau:

--------------------------------------------------------------------------- 
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) 

Các lỗi có ý nghĩa trong đó tôi nghĩ .transform muốn ánh xạ một DataFrame đến một DataFrame. Nhưng có cách nào để thực hiện một hoạt động nhóm trên một DataFrame, chuyển từng đoạn vào một hàm làm giảm nó thành một Series (với cùng một chỉ mục), và sau đó kết hợp Series thành một thứ có thể được chèn vào khung dữ liệu gốc?

Trả lời

2

Phần trên cùng ở đây giống nhau, tôi chỉ sử dụng tập dữ liệu đồ chơi b/c Tôi đang đứng sau tường lửa.

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) 

Nếu bạn thay đổi 'biến' thành 'áp dụng', bạn sẽ nhận được:

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 

Đó không hoàn toàn những gì bạn muốn, nhưng nếu bạn thả level = 0, bạn có thể tiến hành như mong muốn :

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

Thú vị, điều này không làm việc với tập dữ liệu lời khuyên seaborn vì một lỗi liên quan đến 'ngày' là một đối tượng phân loại. Tôi tự hỏi nếu đó là một lỗi trong gấu trúc. – mwaskom

+0

Hoạt động trên tổng thể gấu trúc. Đã xảy ra lỗi với Danh mục không có cờ để tham gia/cuộc hội thoại. – TomAugspurger

+0

Tuyệt. @TomAugspurger, bạn sẽ nói đây là cách thành ngữ nhất để làm điều này trong Pandas? Tôi sẽ đánh dấu đúng nếu có. – mwaskom

0

EDIT:

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

tôi đã phải sửa đổi fit_predict chức năng của bạn để đặt tên cho 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

Tuy nhiên, bạn sẽ lưu ý rằng nó không hoạt động trên ví dụ được đưa ra trong câu hỏi. – mwaskom

+0

Nó không liên quan vì '.describe' ánh xạ một' DataFrame' thành 'DataFrame', không phải là' DataFrame' thành một 'Series'. – mwaskom

+0

Bạn chính xác. Tôi đã sửa đổi câu trả lời của mình để chuyển một DataFrame sang hàm DataFrame thành 'transform'. –

Các vấn đề liên quan