将季度观测值分配给下一季度的月份



考虑一个由某个变量组成的不平衡面板:对于每个组,我观察到一个由季度末日期时间对象标识的季度时间序列。时间序列可能有洞,组可能有不同季度的观测值。

我的目标是,以每个组为条件,将季度末的观察结果分配给下个季度的三个月。以组1的季度2009-12-31的观察4为例。我想为组1生成一个时间序列,该时间序列具有三个月2010-01-31, 2010-02-28, 2010-03-31的观察4,但不适用于2009-12-31

在我的尝试中,我将季度末的观测值偏移了一个月,使用"M"重新采样,然后使用ffill()转发填充。但是,这并不能适当地照顾最后一个季度。虽然,我可以手动处理上个月,但我觉得必须有一个更直接的解决方案。

我感谢任何帮助。

这是MWE:

import pandas as pd
date = pd.to_datetime(['2009-12-31','2010-03-31','2010-06-30','2010-09-30','2014-03-31','2014-06-30','2015-09-30','2015-12-31','2016-03-30'])
group = [1,1,1,1,1,1,2,2,2]
variable = [4,5,6,7,8,9,10,11,12]
data = {'date':date, 'group':group, 'var':variable}
df = pd.DataFrame(data)
df.set_index(['group','date'], inplace=True)

下面是输入数据帧:

var
group date           
1     2009-12-31    4
2010-03-31    5
2010-06-30    6
2010-09-30    7
2014-03-31    8
2014-06-30    9
2     2015-09-30   10
2015-12-31   11
2016-03-30   12

这是我的期望:

var
group date           
1     2010-01-31    4
2010-02-28    4
2010-03-31    4
2010-04-30    5
2010-05-31    5
2010-06-30    5
2010-07-31    6
2010-08-31    6
2010-09-30    6
2010-10-31    7
2010-11-30    7
2010-12-31    7
2014-04-30    8
2014-05-31    8
2014-06-30    8
2014-07-31    9
2014-08-31    9
2014-09-30    9
2     2015-10-31   10
2015-11-30   10
2015-12-31   10
2016-01-31   11
2016-02-28   11
2016-03-31   11
2016-04-30   12
2016-05-31   12
2016-06-30   12

首先创建新组g1,连续季度按DataFrameGroupBy.diff比较每个组的差异,这里是 100 天(3 个月(,下个月也增加了 3 天:

df = df.reset_index()
df['date'] = df['date'] + pd.Timedelta(3, unit='d')
df['g1'] = df.groupby('group')['date'].diff().dt.days.gt(100).cumsum()

然后有必要添加具有上次重复值和未来 2 个月的日期时间的帮助程序DataFrame,以避免仅最后一行:

last = (df.drop_duplicates(['group','g1'], keep='last')
.assign(date = lambda x: x['date'] + pd.offsets.DateOffset(months=2)))
print (last)
group       date  var  g1
3      1 2010-12-03    7   0
5      1 2014-09-03    9   1
8      2 2016-06-02   12   1

加入原件并使用DataFrameGroupBy.resample

df = (pd.concat([df, last])
.set_index('date')
.groupby(['group', 'g1'])['var']
.resample('m')
.ffill()
.reset_index(level=1, drop=True))

print(df)
group  date      
1      2010-01-31     4
2010-02-28     4
2010-03-31     4
2010-04-30     5
2010-05-31     5
2010-06-30     5
2010-07-31     6
2010-08-31     6
2010-09-30     6
2010-10-31     7
2010-11-30     7
2010-12-31     7
2014-04-30     8
2014-05-31     8
2014-06-30     8
2014-07-31     9
2014-08-31     9
2014-09-30     9
2      2015-10-31    10
2015-11-30    10
2015-12-31    10
2016-01-31    11
2016-02-29    11
2016-03-31    11
2016-04-30    12
2016-05-31    12
2016-06-30    12
Name: var, dtype: int64

相关内容

  • 没有找到相关文章

最新更新