【问题标题】:Can pandas groupby transform a DataFrame into a Series?pandas groupby 可以将 DataFrame 转换为 Series 吗?
【发布时间】:2015-09-19 02:56:27
【问题描述】:

我想使用 pandas 和 statsmodels 在数据帧的子集上拟合线性模型并返回预测值。但是,我无法确定要使用的正确 pandas 习语。这是我想要做的:

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 映射到 DataFrame。但是有没有办法对 DataFrame 进行 groupby 操作,将每个块传递给一个函数,将其简化为 Series(具有相同的索引),然后将生成的 Series 组合成可以插入原始数据帧的东西?

【问题讨论】:

    标签: python pandas statsmodels


    【解决方案1】:

    这里的顶部是相同的,我只是在使用一个玩具数据集 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
    

    这不是你想要的,但如果你放弃 level=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
    

    【讨论】:

    • 有趣,这不适用于 seaborn 提示数据集,因为涉及 day 作为分类对象的错误。我想知道这是否是熊猫的一个错误。
    • 适用于熊猫大师。分类有一个错误,没有用于连接/连接的标志。
    • 酷。 @TomAugspurger,你会说这是在 Pandas 中最惯用的方法吗?如果是,我会标记为正确的。
    • 是的。 .transform 是正确的方法,但它要求输出具有相同的索引和列。
    • ignore_index 和/或ignore_columns kwargs 会是合理的建议增强功能吗?如果您认为这会很受欢迎,我可以打开一个问题。
    猜你喜欢
    • 2012-05-09
    • 1970-01-01
    • 2016-12-28
    • 2022-12-01
    • 1970-01-01
    • 2020-05-18
    • 2023-01-08
    • 2020-11-09
    • 2018-04-19
    相关资源
    最近更新 更多