Pandas Groupby并使用自定义函数应用方法

时间:2018-03-26 21:04:30

标签: python pandas pandas-groupby

我构建了以下函数,目的是估计大熊猫DataFrame列的最佳指数移动平均值。

from scipy import optimize
from sklearn.metrics import mean_squared_error
import pandas as pd
## Function that finds best alpha and uses it to create ewma
def find_best_ewma(series, eps=10e-5):

    def f(alpha):
        ewm = series.shift().ewm(alpha=alpha, adjust=False).mean()
        return mean_squared_error(series, ewm.fillna(0))

    result = optimize.minimize(f,.3, bounds=[(0+eps, 1-eps)])

    return series.shift().ewm(alpha=result.x, adjust=False).mean()

现在我想将此函数应用于在以下测试df上使用pandas-groupby创建的每个组:

## test
      data1     data2 key1 key2
0 -0.018442 -1.564270    a    x
1 -0.038490 -1.504290    b    x
2  0.953920 -0.283246    a    x
3 -0.231322 -0.223326    b    y
4 -0.741380  1.458798    c    z
5 -0.856434  0.443335    d    y
6 -1.416564  1.196244    c    z

为此,我尝试了以下两种方式:

## First way
test.groupby(["key1","key2"])["data1"].apply(find_best_ewma)
## Output
0         NaN
1         NaN
2   -0.018442
3         NaN
4         NaN
5         NaN
6   -0.741380
Name: data1, dtype: float64

## Second way
test.groupby(["key1","key2"]).apply(lambda g: find_best_ewma(g["data1"]))
## Output
key1  key2   
a     x     0         NaN
            2   -0.018442
b     x     1         NaN
      y     3         NaN
c     z     4         NaN
            6   -0.741380
d     y     5         NaN
Name: data1, dtype: float64

两种方式都产生一个pandas.core.series.Series,但只有第二种方式才能提供预期的层次索引。

我不明白为什么第一种方法不会产生分层索引而是返回原始数据帧索引。你能解释一下为什么会这样吗?

我错过了什么?

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

第一种方法创建一个pandas.core.groupby.DataFrameGroupBy对象,一旦从中选择一个特定的列,该对象就变成了pandas.core.groupby.SeriesGroupBy对象;正是这个对象应用了'apply'方法,因此返回了一个系列。

test.groupby(["key1","key2"])["data1"]#.apply(find_best_ewma)
<pandas.core.groupby.SeriesGroupBy object at 0x7fce51fac790>

第二种方式仍然是一个DataFrameGroupBy对象。您应用于该对象的函数选择列,这意味着函数'find_best_ewma'应用于该列的每个成员,但是'apply'方法应用于原始DataFrameGroupBy,因此是一个DataFrame返回时,'magic'是因为DataFrame的索引仍然存在。