我构建了以下函数,目的是估计 pandas 的 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 但只有第二种方式提供了预期的分层索引。
我不明白为什么第一种方法不产生分层索引而是返回原始数据帧索引。您能解释一下为什么会发生这种情况吗?
我错过了什么?
预先感谢您的帮助。
最佳答案
第一种方法创建一个 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返回后,“神奇”之处在于 DataFrame 的索引仍然存在。
关于python - Pandas Groupby 和应用具有自定义函数的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49500560/