我构建了以下函数,目的是估计大熊猫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,但只有第二种方式才能提供预期的层次索引。
我不明白为什么第一种方法不会产生分层索引而是返回原始数据帧索引。你能解释一下为什么会这样吗?
我错过了什么?
提前感谢您的帮助。
答案 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的索引仍然存在。