【问题标题】:How to interpolate missing years within pd.groupby()如何在 pd.groupby() 中插入缺失的年份
【发布时间】:2023-02-06 20:12:45
【问题描述】:

问题:

我有一个包含 5 年时间间隔条目的数据框。我需要按“id”列对条目进行分组,并在组中的第一项和最后一项之间插入值。我知道它必须是 groupby()、set_index() 和 interpolate() 的某种组合,但我无法使其适用于整个输入数据帧。

样本 df:

import pandas as pd

data = {
    'id': ['a', 'b', 'a', 'b'],
    'year': [2005, 2005, 2010, 2010],
    'val': [0, 0, 100, 100],
    
}

df = pd.DataFrame.from_dict(data)

示例输入 df:

_    id  year  val
0     a  2005    0
1     a  2010  100
2     b  2005    0
3     b  2010  100

预期输出 df:

_     id  year  val type
0      a  2005    0 original
1      a  2006   20 interpolated
2      a  2007   40 interpolated
3      a  2008   60 interpolated
4      a  2009   80 interpolated
5      a  2010  100 original
6      b  2005    0 original
7      b  2006   20 interpolated
8      b  2007   40 interpolated
9      b  2008   60 interpolated
10     b  2009   80 interpolated
11     b  2010  100 original

“类型”不是必需的,仅用于说明目的。

问题:

如何将缺失的年份添加到 groupby() 视图和 interpolate() 的相应值中?

谢谢你!

【问题讨论】:

    标签: python python-3.x pandas group-by interpolation


    【解决方案1】:

    为每个组独立创建最小和最大年份的解决方案:

    首先通过 DataFrame.reindex 通过最小值和最大值为每组创建缺失值,然后通过 Series.interpolate 进行插值,最后确定从原始 DataFrame 到新列的值:

    df = (df.set_index('year')
            .groupby('id')['val']
            .apply(lambda x: x.reindex(range(x.index.min(), x.index.max() + 1)).interpolate())
            .reset_index()
            .merge(df, how='left', indicator=True)
            .assign(type = lambda x: np.where(x.pop('_merge').eq('both'),
                                              'original',
                                              'interpolated')))
    print (df)
       id  year    val          type
    0   a  2005    0.0      original
    1   a  2006   20.0  interpolated
    2   a  2007   40.0  interpolated
    3   a  2008   60.0  interpolated
    4   a  2009   80.0  interpolated
    5   a  2010  100.0      original
    6   b  2005    0.0      original
    7   b  2006   20.0  interpolated
    8   b  2007   40.0  interpolated
    9   b  2008   60.0  interpolated
    10  b  2009   80.0  interpolated
    11  b  2010  100.0      original
    

    【讨论】:

      【解决方案2】:

      使用 pivotunstackreindex+interpolate 进行临时整形以添加缺失的年份:

      out = (df
         .pivot(index='year', columns='id', values='val')
         .reindex(range(df['year'].min(), df['year'].max()+1))
         .interpolate('index')
         .unstack(-1).reset_index(name='val')
      )
      

      输出:

         id  year    val
      0   a  2005    0.0
      1   a  2006   20.0
      2   a  2007   40.0
      3   a  2008   60.0
      4   a  2009   80.0
      5   a  2010  100.0
      6   b  2005    0.0
      7   b  2006   20.0
      8   b  2007   40.0
      9   b  2008   60.0
      10  b  2009   80.0
      11  b  2010  100.0
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-09-01
        • 2022-12-03
        • 1970-01-01
        • 2013-07-10
        • 1970-01-01
        • 2021-11-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多