【问题标题】:Python pandas: insert rows for missing dates, time series in groupby dataframePython pandas:在groupby数据框中插入缺失日期、时间序列的行
【发布时间】:2020-10-22 17:00:24
【问题描述】:

我有一个数据框df

   Serial_no       date  Index     x    y
           1 2014-01-01      1   2.0  3.0
           1 2014-03-01      2   3.0  3.0
           1 2014-04-01      3   6.0  2.0
           2 2011-03-01      1   5.1  1.3
           2 2011-04-01      2   5.8  0.6
           2 2011-05-01      3   6.5 -0.1
           2 2011-07-01      4   3.0  5.0
           3 2019-10-01      1   7.9 -1.5
           3 2019-11-01      2   8.6 -2.2
           3 2020-01-01      3  10.0 -3.6
           3 2020-02-01      4  10.7 -4.3
           3 2020-03-01      5   4.0  3.0

注意: 数据按Serial_no 分组,date 是每月报告的数据(每月的第一天)。 设置了Index 列,因此每个连续报告的日期都是系列中的一个连续数字。 每组Serial_no上报的日期数量不同。 每组Serial_no 的报告日期间隔date 不同(每组的开始或结束日期不同)。

问题: 时间序列中某些日期date 没有报告数据。请注意,每个 Serial_no 组中缺少一些日期。 我想在每个组中为那些缺少的日期添加一行 date,并将 xy 列中的数据报告为“NaN”。

我需要的数据框示例:

   Serial_no       date  Index       x       y
           1 2014-01-01      1     2.0     3.0
           1 2014-02-01      2     NaN     NaN
           1 2014-03-01      3     3.0     3.0
           1 2014-04-01      4     6.0     2.0
           2 2011-03-01      1     5.1     1.3
           2 2011-04-01      2     5.8     0.6
           2 2011-05-01      3     6.5    -0.1
           2 2011-06-01      4     NaN     NaN
           2 2011-07-01      5     3.0     5.0
           3 2019-10-01      1     7.9    -1.5
           3 2019-11-01      2     8.6    -2.2
           3 2019-12-01      3     NaN     NaN
           3 2020-01-01      4    10.0    -3.6
           3 2020-02-01      5    10.7    -4.3
           3 2020-03-01      6     4.0     3.0

一旦插入缺少日期的行,我知道如何用NaN 替换空白单元格,使用以下代码:

import pandas as pd
import numpy as np

df['x'].replace('', np.nan, inplace=True)
df['y'].replace('', np.nan, inplace=True)

我还知道如何在插入缺少日期的行后使用以下代码重置索引:

df["Index"] = df.groupby("Serial_no",).cumcount('date')

但是,我不确定如何找到每个组中缺少的日期并为这些(每月报告的)日期插入行。任何帮助表示赞赏。

【问题讨论】:

    标签: python pandas dataframe time-series data-science


    【解决方案1】:

    GroupBy.apply 中使用带有DataFrame.asfreq 的自定义函数,然后通过GroupBy.cumcount 重新分配Index

    df['date'] = pd.to_datetime(df['date'])
    
    df = (df.set_index('date')
            .groupby('Serial_no')
            .apply(lambda x: x.asfreq('MS'))
            .drop('Serial_no', axis=1))
    df = df.reset_index()
    df["Index"] = df.groupby("Serial_no").cumcount() + 1
    print (df)
        Serial_no       date  Index     x    y
    0           1 2014-01-01      1   2.0  3.0
    1           1 2014-02-01      2   NaN  NaN
    2           1 2014-03-01      3   3.0  3.0
    3           1 2014-04-01      4   6.0  2.0
    4           2 2011-03-01      1   5.1  1.3
    5           2 2011-04-01      2   5.8  0.6
    6           2 2011-05-01      3   6.5 -0.1
    7           2 2011-06-01      4   NaN  NaN
    8           2 2011-07-01      5   3.0  5.0
    9           3 2019-10-01      1   7.9 -1.5
    10          3 2019-11-01      2   8.6 -2.2
    11          3 2019-12-01      3   NaN  NaN
    12          3 2020-01-01      4  10.0 -3.6
    13          3 2020-02-01      5  10.7 -4.3
    14          3 2020-03-01      6   4.0  3.0
    

    DataFrame.reindex 的替代解决方案:

    df['date'] = pd.to_datetime(df['date'])
    
    f = lambda x: x.reindex(pd.date_range(x.index.min(), x.index.max(), freq='MS', name='date'))
    df = df.set_index('date').groupby('Serial_no').apply(f).drop('Serial_no', axis=1)
    df = df.reset_index()
    df["Index"] = df.groupby("Serial_no").cumcount() + 1
    

    【讨论】:

    • 完美!谢谢。
    • 嗨@jezrael,如果我想在每个组中添加相同范围的日期,我该怎么做?
    猜你喜欢
    • 1970-01-01
    • 2018-02-02
    • 2020-02-16
    • 2020-04-12
    • 2013-05-23
    • 1970-01-01
    • 2021-06-17
    • 2015-09-17
    • 2016-11-16
    相关资源
    最近更新 更多