通过ID用最接近的值填充NaN-熊猫

时间:2019-10-12 08:59:08

标签: pandas

这是我的数据框:

ID  Date        X   Y
1   07-16-2019  30  3
1   07-17-2019  41  4
1   07-20-2019  50  5
1   07-22-2019  60  6
2   07-20-2019  10  1
2   07-22-2019  20  2
2   07-23-2019  30  3

首先,我想“拉伸”每个ID的数据,从最小日期值到最大日期值。在此示例中:从07-16-2019到07-23-2019。

在执行上述步骤后,数据应该是这样:

ID  Date        X   Y
1   07-16-2019  30  3
1   07-17-2019  41  4
1   07-18-2019  NaN NaN
1   07-19-2019  NaN NaN
1   07-20-2019  50  5
1   07-21-2019  NaN NaN
1   07-22-2019  60  6
1   07-23-2019  NaN NaN
2   07-16-2019  NaN NaN
2   07-17-2019  NaN NaN
2   07-18-2019  NaN NaN
2   07-19-2019  NaN NaN
2   07-20-2019  10  1
2   07-21-2019  NaN NaN
2   07-22-2019  20  2
2   07-23-2019  30  3

然后,我想用最接近的值(也许用'interpolate')填充NaN值。

预期结果:

ID  Date        X   Y
1   07-16-2019  30  3
1   07-17-2019  41  4
1   07-18-2019  41  4
1   07-19-2019  50  5
1   07-20-2019  50  5
1   07-21-2019  50  5
1   07-22-2019  60  6
1   07-23-2019  60  6
2   07-16-2019  10  1
2   07-17-2019  10  1
2   07-18-2019  10  1
2   07-19-2019  10  1
2   07-20-2019  10  1
2   07-21-2019  10  1
2   07-22-2019  20  2
2   07-23-2019  30  3

2 个答案:

答案 0 :(得分:1)

使用pd.date_range 来填充日期列的最大值和最小值之间的间隙。然后,您可以使用ID使用Dategroupby.apply + Dataframe.reindex来扩展数据帧。索引。 用fillna填充每个列ID的间隙。最后使用Xinterpolate + bfill + ffill来填充YID

df['Date']=pd.to_datetime(df['Date'])
ind=pd.date_range(start=df['Date'].min(), end=df['Date'].max())
new_df=(df.set_index('Date').groupby('ID').apply(lambda x: x.reindex(ind).reset_index(level=0).fillna({'ID':x['ID'].mean()}).interpolate(method='nearest').ffill().bfill())
                                       .rename(columns={'index':'Date'}).reset_index(drop=True)
                                       .reindex(columns=['ID','Date','X','Y']))
print(new_df)
     ID       Date     X    Y
0   1.0 2019-07-16  30.0  3.0
1   1.0 2019-07-17  41.0  4.0
2   1.0 2019-07-18  41.0  4.0
3   1.0 2019-07-19  50.0  5.0
4   1.0 2019-07-20  50.0  5.0
5   1.0 2019-07-21  50.0  5.0
6   1.0 2019-07-22  60.0  6.0
7   1.0 2019-07-23  60.0  6.0
8   2.0 2019-07-16  10.0  1.0
9   2.0 2019-07-17  10.0  1.0
10  2.0 2019-07-18  10.0  1.0
11  2.0 2019-07-19  10.0  1.0
12  2.0 2019-07-20  10.0  1.0
13  2.0 2019-07-21  10.0  1.0
14  2.0 2019-07-22  20.0  2.0
15  2.0 2019-07-23  30.0  3.0

答案 1 :(得分:1)

创建从minmax的date_range。根据{{​​1}}和date_range创建multiidex。最后,IDset_indexreindexreset_index。您还需要其他interpolatebfill来处理ffill

的特殊情况
nearest

通过s = pd.date_range(df.Date.min(), df.Date.max(), name='Date') ix = pd.MultiIndex.from_product([df.ID.unique(), s], names=['ID','Date']) df1 = (df.set_index(['ID', 'Date']).reindex(ix).reset_index().groupby('ID') .apply(lambda x: x.interpolate('nearest').bfill().ffill())) Out[62]: ID Date X Y 0 1 2019-07-16 30.0 3.0 1 1 2019-07-17 41.0 4.0 2 1 2019-07-18 41.0 4.0 3 1 2019-07-19 50.0 5.0 4 1 2019-07-20 50.0 5.0 5 1 2019-07-21 50.0 5.0 6 1 2019-07-22 60.0 6.0 7 1 2019-07-23 60.0 6.0 8 2 2019-07-16 10.0 1.0 9 2 2019-07-17 10.0 1.0 10 2 2019-07-18 10.0 1.0 11 2 2019-07-19 10.0 1.0 12 2 2019-07-20 10.0 1.0 13 2 2019-07-21 10.0 1.0 14 2 2019-07-22 20.0 2.0 15 2 2019-07-23 30.0 3.0

进行插值

仅重置索引time,将ID保留在索引中。将方法更改为date。其余部分相同。请注意time2019-07-17 1 41.0 4.000000之间的值。那些2019-07-20 1 50.0 5.000000被均匀的空格值填充。 也就是说,它类似于NaNlinear忽略索引,而linear则基于time

datetimeindex