Python pandas:在groupby数据框中插入缺失日期、时间序列的行

Posted

技术标签:

【中文标题】Python pandas:在groupby数据框中插入缺失日期、时间序列的行【英文标题】:Python pandas: insert rows for missing dates, time series in groupby dataframe 【发布时间】: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')

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

【问题讨论】:

【参考方案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,如果我想在每个组中添加相同范围的日期,我该怎么做?

以上是关于Python pandas:在groupby数据框中插入缺失日期、时间序列的行的主要内容,如果未能解决你的问题,请参考以下文章

Python Pandas 如何将 groupby 操作结果分配回父数据框中的列?

如何在python中使用groupby或pivot在这个pandas数据框中[重复]

Python pandas数据框根据条件分组

Python Pandas DF Pivot 和 Groupby

使用 pandas 在数据帧上执行 groupby,按计数排序并获取 python 中的前 2 个计数

python--pandas分组聚合