首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Pandas Dataframe Groupby.agg()中,将多个列组合为lambda函数的参数

在Pandas Dataframe Groupby.agg()中,将多个列组合为lambda函数的参数
EN

Stack Overflow用户
提问于 2019-12-06 13:37:12
回答 1查看 68关注 1票数 1

我希望能够创建一个聚合groupby列,该列是从一个聚合函数创建的,该聚合函数依赖于原始数据帧的多个列。例如(在本例中),我希望计算具有给定半衰期的资产列表的指数加权平均值。

这是一个例子,我计算了内置函数的均值和标准差,以及lambda函数的均值……

代码语言:javascript
复制
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’列……

代码语言:javascript
复制
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‘列。

我确实成功地将其计算为一个单独的列,如下所示…

代码语言:javascript
复制
stats2 = df.groupby('ASSET').agg(lambda x: (np.exp(k * x['RANK']) * x['MARKET_VALUE']).sum() / np.exp(k * x['RANK']).sum())

但它为多个列提供了相同的值:

代码语言:javascript
复制
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

如果我尝试组合其中的一个以上,我会得到一个键错误:

代码语言:javascript
复制
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,可能还有其他统计数据),每个函数都为每个统计数据返回一列。谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-12-06 14:48:09

你在stats2上的方法很接近。尝试使用apply而不是agg。然后将其分配回stats的列'ewm',以组合结果。

代码语言:javascript
复制
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
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59207470

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档