首页 > 解决方案 > Pandas - 在具有不同时间范围的组中填充缺失的日期

问题描述

我正在使用一个数据集,其中包含有关多个用户的每月信息。并且每个用户都有不同的时间范围。每个用户也缺少“时间”数据。我想做的是根据每个用户的时间范围(从 min.time 到 max.time 以月为单位)为每个用户填写缺少的月份数据

我已经阅读了使用 re-sample, re-index from here 的类似情况的方法,但我没有得到所需的输出/在填充缺失的月份后存在行不匹配。

任何帮助/指针将不胜感激。

-卢克

尝试使用重新采样、重新索引,但未获得所需的输出

x = pd.DataFrame({'user': ['a','a','b','b','c','a','a','b','a','c','c','b'], 'dt': ['2015-01-01','2015-02-01', '2016-01-01','2016-02-01','2017-01-01','2015-05-01','2015-07-01','2016-05-01','2015-08-01','2017-03-01','2017-08-01','2016-09-01'], 'val': [1,33,2,1,5,4,2,5,66,7,5,1]})
     date        id  value
0   2015-01-01    a    1
1   2015-02-01    a   33
2   2016-01-01    b    2
3   2016-02-01    b    1
4   2017-01-01    c    5
5   2015-05-01    a    4
6   2015-07-01    a    2
7   2016-05-01    b    5
8   2015-08-01    a    66
9   2017-03-01    c    7
10  2017-08-01    c    5
11  2016-09-01    b    1

我想看到的是 - 对于每个“id”,根据该 id 的 min.date 和 max.date 生成缺失的月份,并用 0 填充那些月份的“val”。

标签: python-3.xpandaspandas-groupby

解决方案


创建DatetimeIndex,因此可能groupby与自定义 lambda 函数和 一起使用Series.asfreq

x['dt'] = pd.to_datetime(x['dt'])
x = (x.set_index('dt')
      .groupby('user')['val']
      .apply(lambda x: x.asfreq('MS', fill_value=0))
      .reset_index())
print (x)
   user         dt  val
0     a 2015-01-01    1
1     a 2015-02-01   33
2     a 2015-03-01    0
3     a 2015-04-01    0
4     a 2015-05-01    4
5     a 2015-06-01    0
6     a 2015-07-01    2
7     a 2015-08-01   66
8     b 2016-01-01    2
9     b 2016-02-01    1
10    b 2016-03-01    0
11    b 2016-04-01    0
12    b 2016-05-01    5
13    b 2016-06-01    0
14    b 2016-07-01    0
15    b 2016-08-01    0
16    b 2016-09-01    1
17    c 2017-01-01    5
18    c 2017-02-01    0
19    c 2017-03-01    7
20    c 2017-04-01    0
21    c 2017-05-01    0
22    c 2017-06-01    0
23    c 2017-07-01    0
24    c 2017-08-01    5

或使用Series.reindex每组的最小和最大日期时间:

x = (x.set_index('dt')
      .groupby('user')['val']
      .apply(lambda x: x.reindex(pd.date_range(x.index.min(), 
                                               x.index.max(), freq='MS'), fill_value=0))
      .rename_axis(('user','dt'))
      .reset_index())

推荐阅读