我希望能够创建一个聚合groupby列,该列是从一个聚合函数创建的,该聚合函数依赖于原始数据帧的多个列。例如(在本例中),我希望计算具有给定半衰期的资产列表的指数加权平均值。
这是一个例子,我计算了内置函数的均值和标准差,以及lambda函数的均值……
np.random.seed(0)
df = pd.DataFrame({'DATE': ['2019-11-30','2019-10-31', '2019-09-30', '2019-08-31', '2019-07-31', '2019-06-30',
'2019-11-30','2019-10-31', '2019-09-30', '2019-08-31', '2019-07-31', '2019-06-30',
'2019-11-30','2019-10-31', '2019-09-30', '2019-08-31', '2019-07-31', '2019-06-30'
],
'ASSET': ['ASSET1', 'ASSET1', 'ASSET1', 'ASSET1', 'ASSET1', 'ASSET1',
'ASSET2', 'ASSET2', 'ASSET2', 'ASSET2', 'ASSET2', 'ASSET2',
'ASSET3', 'ASSET3', 'ASSET3', 'ASSET3', 'ASSET3', 'ASSET3'
],
'MARKET_VALUE': [10] * 6 + [15] * 6 + [20] * 6 + np.random.randint(-50,50,18,)/100
}
)
df['DATE'] = df['DATE'].map(lambda x: datetime.datetime.strptime(x, '%Y-%m-%d'))
df['RANK'] = df.groupby('ASSET')['DATE'].rank(ascending=False) - 1
df = df.sort_values(by=['ASSET', 'RANK'])
print(df)
DATE ASSET MARKET_VALUE RANK
0 2019-11-30 ASSET1 9.94 0.0
1 2019-10-31 ASSET1 9.97 1.0
2 2019-09-30 ASSET1 10.14 2.0
3 2019-08-31 ASSET1 10.17 3.0
4 2019-07-31 ASSET1 10.17 4.0
5 2019-06-30 ASSET1 9.59 5.0
6 2019-11-30 ASSET2 15.33 0.0
7 2019-10-31 ASSET2 14.71 1.0
8 2019-09-30 ASSET2 14.86 2.0
9 2019-08-31 ASSET2 15.37 3.0
10 2019-07-31 ASSET2 15.20 4.0
11 2019-06-30 ASSET2 15.38 5.0
12 2019-11-30 ASSET3 20.38 0.0
13 2019-10-31 ASSET3 19.62 1.0
14 2019-09-30 ASSET3 20.08 2.0
15 2019-08-31 ASSET3 20.15 3.0
16 2019-07-31 ASSET3 19.89 4.0
17 2019-06-30 ASSET3 20.37 5.0
stats = df.groupby('ASSET').agg({'MARKET_VALUE': {'count': 'count',
'mean': 'mean',
'std': 'std',
'meanLambda': (lambda x: x.sum() / x.count()),
}
}
)
print(stats)
stats
MARKET_VALUE
count mean std meanLambda
ASSET
ASSET1 6 9.996667 0.223577 9.996667
ASSET2 6 15.141667 0.287570 15.14167
ASSET3 6 20.081667 0.292124 20.081667
现在我想添加另一个lambda函数,它使用了'RANK‘列和'MARKET_VALUE’列……
halflife = 6
k = math.log(.5) / halflife
stats = df.groupby('ASSET').agg({'MARKET_VALUE': {'count': 'count',
'mean': 'mean',
'std': 'std',
'mean2': (lambda x: x.sum() / x.count()),
'ewm': (lambda x: (np.exp(k * df['RANK']) * x).sum())/(np.exp(k * df['RANK'])).sum()
}
}
)
但是我得到了一个错误,因为我们只能访问x,'MARKET_VALUE‘列。
我确实成功地将其计算为一个单独的列,如下所示…
stats2 = df.groupby('ASSET').agg(lambda x: (np.exp(k * x['RANK']) * x['MARKET_VALUE']).sum() / np.exp(k * x['RANK']).sum())
但它为多个列提供了相同的值:
stats2
DATE MARKET_VALUE RANK
ASSET
ASSET1 10.004711 10.004711 10.004711
ASSET2 15.122501 15.122501 15.122501
ASSET3 20.076236 20.076236 20.076236
如果我尝试组合其中的一个以上,我会得到一个键错误:
stats3 = df.groupby('ASSET').agg([lambda x: x['MARKET_VALUE'].count(),lambda x: (np.exp(k * x['RANK']) * x['MARKET_VALUE']).sum() / np.exp(k * x['RANK']).sum()])
File "C:\Users\p814635\AppData\Local\Programs\Python\Python37\lib\site-packages\pandas\core\indexes\base.py", line 4730, in get_value
return self._engine.get_value(s, k, tz=getattr(series.dtype, "tz", None))
File "pandas\_libs\index.pyx", line 80, in pandas._libs.index.IndexEngine.get_value
File "pandas\_libs\index.pyx", line 88, in pandas._libs.index.IndexEngine.get_value
File "pandas\_libs\index.pyx", line 128, in pandas._libs.index.IndexEngine.get_loc
File "pandas\_libs\index_class_helper.pxi", line 91, in pandas._libs.index.Int64Engine._check_type
KeyError: 'MARKET_VALUE'
因此,一般来说,我希望访问agg lambda函数中的任何列(它只返回一列),并且能够拥有多个函数(比如meanLambda和stdLambda,可能还有其他统计数据),每个函数都为每个统计数据返回一列。谢谢。
发布于 2019-12-06 14:48:09
你在stats2
上的方法很接近。尝试使用apply
而不是agg
。然后将其分配回stats
的列'ewm'
,以组合结果。
stats2 = df.groupby('ASSET').apply(lambda x: (np.exp(k * x['RANK']) * x['MARKET_VALUE']).sum() / np.exp(k * x['RANK']).sum())
stats['ewm'] = stats2
MARKET_VALUE ewm
count mean std mean2
ASSET
ASSET1 6 9.996667 0.223577 9.996667 10.004711
ASSET2 6 15.141667 0.287570 15.141667 15.122501
ASSET3 6 20.081667 0.292124 20.081667 20.076236
https://stackoverflow.com/questions/59207470
复制相似问题