【问题标题】:Pandas - Filling missing dates within groups with different time rangesPandas - 在具有不同时间范围的组中填充缺失的日期
【发布时间】:2019-12-26 17:11:43
【问题描述】:

我正在使用一个数据集,其中包含有关多个用户的每月信息。并且每个用户都有不同的时间范围。每个用户也缺少“时间”数据。我想做的是根据每个用户的时间范围(从 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.x pandas pandas-groupby


    【解决方案1】:

    创建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())
    

    【讨论】:

    • 非常感谢,杰兹瑞尔。这对我有用。我的代码中不需要的行造成了麻烦,但感谢您的快速响应。
    猜你喜欢
    • 2021-03-19
    • 1970-01-01
    • 1970-01-01
    • 2022-08-15
    • 2011-04-02
    • 1970-01-01
    • 1970-01-01
    • 2019-02-21
    • 2015-10-19
    相关资源
    最近更新 更多