在pandas中获取groupby的最大和最小之差,并计算出平均数

1 人关注

我有一个数据框架,如下所示。

ticker  fy  fp  value   f_date  rn
MSFT    2009    0   144 2010-01-01T12:12:34 0
AAPL    2010    0   144 2010-01-01T12:12:34 0
MSFT    2009    0   48  2014-05-01T12:12:34 1
AAPL    2011    0   80  2012-01-01T12:12:34 1
GOOG    2010    0   40  2010-01-01T12:12:34 0

我只想在tickerfyfp的基础上对这些数据进行分组,如下所示

df.groupby(by=['ticker', 'fy', 'fp'])

在此基础上,我只想计算f_date中的maxmin的差值,并将其除以max of rn。例如,组MSFT, 2009, 0,最大日期是2014-05-01T12:12:34,最小日期是2010-01-01T12:12:34,而最大rn是1,所以我想把它计算成max(f_date) - min(f_date)/ max(rn+1)。因此,我将得到这两个日期之间的天数,因此我可以将这些数据与其他数据进行映射,以做一些分析。

我在组别后无法继续前进。

python
pandas
ggupta
ggupta
发布于 2019-12-23
1 个回答
jezrael
jezrael
发布于 2019-12-23
已采纳
0 人赞同

对于pandas 0.25以上的版本,可以使用 命名聚合 ,然后进行减法和除法列。

df['f_date'] = pd.to_datetime(df['f_date'])
df = df.groupby(by=['ticker', 'fy', 'fp']).agg(min1=('f_date','min'),
                                               max1=('f_date','max'),
                                               rn=('rn', 'max'))
df['new'] = df['max1'].sub(df['min1']).div(df['rn'].add(1))
print (df)
                              min1                max1  rn               new
ticker fy   fp                                                              
AAPL   2010 0  2010-01-01 12:12:34 2010-01-01 12:12:34   0   0 days 00:00:00
       2011 0  2012-01-01 12:12:34 2012-01-01 12:12:34   1   0 days 00:00:00
GOOG   2010 0  2010-01-01 12:12:34 2010-01-01 12:12:34   0   0 days 00:00:00
MSFT   2009 0  2010-01-01 12:12:34 2014-05-01 12:12:34   1 790 days 12:00:00

或者,如果有必要的话,通过以下方式将日期时间(timedeltas)的差异转换为秒。Series.dt.total_seconds:

df['new1'] = df['max1'].sub(df['min1']).dt.total_seconds().div(df['rn'].add(1))
print (df)
                              min1                max1  rn         new
ticker fy   fp                                                        
AAPL   2010 0  2010-01-01 12:12:34 2010-01-01 12:12:34   0         0.0
       2011 0  2012-01-01 12:12:34 2012-01-01 12:12:34   1         0.0
GOOG   2010 0  2010-01-01 12:12:34 2010-01-01 12:12:34   0         0.0
MSFT   2009 0  2010-01-01 12:12:34 2014-05-01 12:12:34   1  68299200.0

为较旧的pandas版本提供解决方案。

df['f_date'] = pd.to_datetime(df['f_date'])
df = df.groupby(by=['ticker', 'fy', 'fp']).agg({'f_date':['min','max'],
                                               'rn':'max'})
df.columns = df.columns.map('_'.join)
df['new'] = df['f_date_max'].sub(df['f_date_min']).div(df['rn_max'].add(1))
print (df)
                        f_date_min          f_date_max  rn_max  \
ticker fy   fp                                                   
AAPL   2010 0  2010-01-01 12:12:34 2010-01-01 12:12:34       0   
       2011 0  2012-01-01 12:12:34 2012-01-01 12:12:34       1   
GOOG   2010 0  2010-01-01 12:12:34 2010-01-01 12:12:34       0   
MSFT   2009 0  2010-01-01 12:12:34 2014-05-01 12:12:34       1   
ticker fy   fp                    
AAPL   2010 0    0 days 00:00:00  
       2011 0    0 days 00:00:00  
GOOG   2010 0    0 days 00:00:00  
MSFT   2009 0  790 days 12:00:00  

最后,如果有必要,将MultiIndex转换为列。

df = df.reset_index()
print (df)
  ticker    fy  fp          f_date_min          f_date_max  rn_max  \
0   AAPL  2010   0 2010-01-01 12:12:34 2010-01-01 12:12:34       0   
1   AAPL  2011   0 2012-01-01 12:12:34 2012-01-01 12:12:34       1   
2   GOOG  2010   0 2010-01-01 12:12:34 2010-01-01 12:12:34       0   
3   MSFT  2009   0 2010-01-01 12:12:34 2014-05-01 12:12:34       1