代码之家  ›  专栏  ›  技术社区  ›  Kevin

按组、大熊猫或numpy填充值之间的不适用项

  •  0
  • Kevin  · 技术社区  · 7 年前

    我有一个DF看起来像

    df=pd.DataFrame.from_items([('i', [1, 1, 2,2]), ('j', [3, 3, 3,3]), ('t', [20170101, 20170115, 20170108,20170129]), ('x', [1.2, 1.4, 8,8.3])])
    

    >>> df
       i  j          t    x
    0  1  3  20170101  1.2
    1  1  3  20170115  1.4
    2  2  3  20170108  8.0
    3  2  3  20170129  8.3
    

    第i列和第j列标识了数据的一个维度(思考人和地点),而t表示i、j的另一个维度。时间频率为每周Y、M、D格式。列x是数据(也可能有一列y包含其他数据等)。

    我需要做的是填写每个I,j的缺失日期,但根据DF中的内容允许不同的开始和结束时间。在本例中,1,3缺少20170108,2,3同时缺少20170115和20170122。因此,填写的DF应如下所示:

    >>> df
       i  j          t    x
    0  1  3  20170101  1.2
    1  1  3  20170108  N/A
    2  1  3  20170115  1.4
    3  2  3  20170108  8.0
    4  2  3  20170115  N/A
    5  2  3  20170122  N/A
    6  2  3  20170129  8.3
    

    实际上,更好的方法是用周围观察值的平均值来代替N/A,或者可能只是将最后观察到的x向前推进。对于后一种情况,类似这样

    >>> df
       i  j          t    x
    0  1  3  20170101  1.2
    1  1  3  20170108  1.2
    2  1  3  20170115  1.4
    3  2  3  20170108  8.0
    4  2  3  20170115  8.0
    5  2  3  20170122  8.0
    6  2  3  20170129  8.3
    

    这似乎是pd.resample的一个更复杂版本,但我不知道如何仅填充基于I,j的不同观察终点。实际的DFs非常大(百万行中的10s)。

    在numpy中找到一个解决方案也很好。

    1 回复  |  直到 7 年前
        1
  •  2
  •   Scott Boston    7 年前

    让我们使用DateTimeIndex和 resample . 首先,我们需要将t列转换为datetime数据类型,并将t列设置为索引。 groupby 要填补每周数据空白:

    df=pd.DataFrame.from_items([('i', [1, 1, 2,2]), ('j', [3, 3, 3,3]), ('t', [20170101, 20170115, 20170108,20170129]), ('x', [1.2, 1.4, 8,8.3])])
    df['t'] = pd.to_datetime(df.t, format=('%Y%m%d')) 
    

    df.set_index('t').groupby(['i','j'])['x'].resample('W').asfreq().reset_index()
    
       i  j          t    x
    0  1  3 2017-01-01  1.2
    1  1  3 2017-01-08  NaN
    2  1  3 2017-01-15  1.4
    3  2  3 2017-01-08  8.0
    4  2  3 2017-01-15  NaN
    5  2  3 2017-01-22  NaN
    6  2  3 2017-01-29  8.3
    

    ffill dt.strftime 要获得最终输出:

    df = df.set_index('t').groupby(['i','j'])['x'].resample('W').ffill().reset_index()
    df['t'] = df['t'].dt.strftime('%Y%m%d)
    

    最终输出:

       i  j         t    x
    0  1  3  20170101  1.2
    1  1  3  20170108  1.2
    2  1  3  20170115  1.4
    3  2  3  20170108  8.0
    4  2  3  20170115  8.0
    5  2  3  20170122  8.0
    6  2  3  20170129  8.3