Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Dataframe Groupby.agg()中,将多个列组合为lambda函数的参数_Dataframe_Lambda_Aggregate_Pandas Groupby_Multiple Columns - Fatal编程技术网

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

在Dataframe Groupby.agg()中,将多个列组合为lambda函数的参数,dataframe,lambda,aggregate,pandas-groupby,multiple-columns,Dataframe,Lambda,Aggregate,Pandas Groupby,Multiple Columns,我希望能够创建一个聚合groupby列,该列是从一个聚合函数创建的,该聚合函数依赖于原始dataframe的多个列。例如(在本例中),我想计算具有给定半衰期的资产列表的指数加权平均值 这里是一个例子,我从内置函数计算平均值和标准差,从lambda函数计算平均值 np.random.seed(0) df = pd.DataFrame({'DATE': ['2019-11-30','2019-10-31', '2019-09-30', '2019-08-31', '2019-07-31', '201

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

这里是一个例子,我从内置函数计算平均值和标准差,从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,即“市场价值”列

我确实成功地将它作为一个列进行了计算,如下所示

stats2 = df.groupby('ASSET').agg(lambda x: (np.exp(k * x['RANK']) * x['MARKET_VALUE']).sum() / np.exp(k * x['RANK']).sum())
但is为多个列提供相同的值:

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,可能还有其他统计数据),每个函数的每个统计数据都返回一列。谢谢。

您在
stats2
上的接近。尝试使用
apply
而不是
agg
。然后将其分配回
stats
'ewm'
列以合并结果

stats2=df.groupby('ASSET').apply(lambda x:(np.exp(k*x['RANK'])*x['MARKET\u VALUE']).sum()/np.exp(k*x['RANK']).sum())
stats['ewm']=stats2
市场价值ewm
计数平均std平均值2
资产
资产16 9.996667 0.223577 9.996667 10.004711
资产2 15.141667 0.287570 15.141667 15.122501
资产36 20.081667 0.292124 20.081667 20.076236

您在
stats2
上的接近接近。尝试使用
apply
而不是
agg
。然后将其分配回
stats
'ewm'
列以合并结果

stats2=df.groupby('ASSET').apply(lambda x:(np.exp(k*x['RANK'])*x['MARKET\u VALUE']).sum()/np.exp(k*x['RANK']).sum())
stats['ewm']=stats2
市场价值ewm
计数平均std平均值2
资产
资产16 9.996667 0.223577 9.996667 10.004711
资产2 15.141667 0.287570 15.141667 15.122501
资产36 20.081667 0.292124 20.081667 20.076236

感谢您的快速响应!它工作得很好。我还在前面插入了行
stats.columns=stats.columns.droplevel()
,以便列索引与其他列一致。干杯…感谢您的快速响应!它工作得很好。我还在前面插入了行
stats.columns=stats.columns.droplevel()
,以便列索引与其他列一致。干杯