将季度数据帧转换为每月数据帧,并填充每个 ID 的缺失值

Convert quarterly dataframe to monthly and fill missing values for each ID

提问人:Tyler D 提问时间:9/3/2021 最后编辑:Tyler D 更新时间:9/6/2021 访问量:510

问:

我有一个数据帧,对于每个 ID,它都包含一个时间戳和一个值。时间戳是给定季度的时间戳:

import pandas as pd
a = pd.DataFrame({'id': [1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,3],
                  'date': ['2002Q1', '2002Q2', '2002Q3', '2002Q4', '2003Q1', '2002Q2', '2002Q3', '2002Q4', '2003Q1', '2002Q2', '2002Q3', '2002Q4', '2003Q1', '2002Q2', '2002Q3', '2002Q4'],
                  'value': [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]})

现在,我想将数据帧扩展到每月频率。这意味着每一行都扩展到三行(即,一个季度变成 3 个月),并且任何给定季度中的所有月份都应具有相同的值。

例如,我们中的前两行扩展到 6 行:a

pd.DataFrame({'id': [1,1,1,1,1,1],
              'date': ['2002-1', '2002-2', '2002-3', '2002-4', '2002-5', '2002-6'],
              'value': [1,1,1,2,2,2]})

所以基本上,我正在做与这个答案相同的操作,但现在涉及一个 ID。

可以这样做吗?


编辑:每个组的最后一个值也需要扩展。当前的解决方案给出了这个结果,这是错误的:

import pandas as pd
a = pd.DataFrame({'id': [1,1],
                  'date': ['2002Q1', '2002Q2'],
                  'value': [1,2]})

mask = a['id'].duplicated(keep='last')
dates = pd.to_datetime(a['date'])
a.index = dates.where(mask, dates + pd.DateOffset(months=2))

a = a.groupby('id')['value'].resample('MS').first().ffill().reset_index()
a['date'] = a['date'].dt.to_period('M')
a


    id  date    value
0   1   2002-01 1.0 # fine
1   1   2002-02 1.0 # fine
2   1   2002-03 1.0 # fine
3   1   2002-04 1.0 # should be 2
4   1   2002-05 1.0 # should be 2
5   1   2002-06 2.0 # fine
Python Pandas 数据帧

评论

0赞 sammywemmy 9/3/2021
这有点不清楚。所以你用 1 替换 1、2、3、4?也许分享更多细节
0赞 Tyler D 9/3/2021
@sammywemmy 请参阅更新的 OP

答:

2赞 mozway 9/3/2021 #1

我想你可以和:groupbyresample

a['date'] = pd.to_datetime(a['date'])
(a.set_index('date')
  .groupby('id')
   ['value']
  .resample('MS')
  .first().ffill()
  .reset_index()
)

输出:

        date   id  value
0 2002-01-01  1.0    1.0
1 2002-02-01  1.0    1.0
2 2002-03-01  1.0    1.0
3 2002-04-01  1.0    2.0
4 2002-05-01  1.0    2.0

评论

0赞 Tyler D 9/3/2021
这不是每个 ID
1赞 jezrael 9/3/2021 #2

首先创建,然后使用 groupby 和 with 并转发填充缺失值,最后将列转换为月份周期:DatetimeIndexresamplefirst

因为缺少过去 2 个月的 per 是在之前手动添加的:idgroupby

import pandas as pd
a = pd.DataFrame({'id': [1,1],
                  'date': ['2002Q1', '2002Q2'],
                  'value': [1,2]})

a.index = pd.to_datetime(a['date'])
mask = a['id'].duplicated(keep='last')
a = pd.concat([a, a[~mask].rename(lambda x: x + pd.DateOffset(months=2))])


a = a.groupby('id')['value'].resample('MS').first().ffill().reset_index()
a['date'] = a['date'].dt.to_period('M')
print (a)
   id     date  value
0   1  2002-01    1.0
1   1  2002-02    1.0
2   1  2002-03    1.0
3   1  2002-04    2.0
4   1  2002-05    2.0
5   1  2002-06    2.0

评论

1赞 Tyler D 9/3/2021
我注意到以 Q1 结尾的日期不会扩展到第 1-2-3 个月。你知道这是为什么吗?
0赞 Tyler D 9/3/2021
更正:如果一个想法只有一个时间戳,那么它不会扩展到三个月。最后一个时间戳也是如此:它不会扩展到三行 - 这是为什么?
1赞 jezrael 9/3/2021
@TylerD - 因为它是每个组的最后一个值,因此需要对此进行更正
0赞 Tyler D 9/3/2021
是否有可能对此进行纠正?每个组的最后/唯一值也应扩展
1赞 jezrael 9/3/2021
@TylerD - 对于每个添加的最后一个值,每个添加 2 个月。添加到答案中。id