通过ID将填充的NaN向前填充到最后一个值,并在最后一个值之后再填充两次

时间:2020-06-02 08:20:31

标签: python pandas dataframe

任务

我有以下df,并希望使用先前的值向前填充每个id的NaN。在每列的最后一个值上,我希望它仅向前填充2次。

我目前正在使用此

df.set_index(['id', 'date'], inplace=True)
df = df.ffill().where(df.bfill().notnull()) 

但是,它向前填充的次数超过了所需的2倍。任何帮助都将是超级!

df

   id      date     compname   fyr
1   1   2016-02-29     a        5.0
2   1   2016-03-31    NaN       NaN
3   1   2016-04-30    NaN       NaN
4   1   2016-05-31     a        5.0
5   1   2016-06-30    NaN       NaN
6   1   2016-07-31    NaN       NaN
7   1   2016-08-31     a        5.0
8   1   2016-09-30    NaN       NaN
9   1   2016-10-31    NaN       NaN
10  1   2016-11-30     a        5.0
11  1   2016-12-31    NaN       NaN
12  1   2017-01-31    NaN       NaN
13  1   2017-02-28    NaN       NaN
14  1   2017-03-31    NaN       NaN
15  2   2016-02-29     b        5.0
16  2   2016-03-31    NaN       NaN
17  2   2016-04-30    NaN       NaN
18  2   2016-05-31     b        5.0
19  2   2016-06-30    NaN       NaN
20  2   2016-07-31    NaN       NaN
21  2   2016-08-31     b        5.0
22  2   2016-09-30    NaN       NaN
23  2   2016-10-31    NaN       NaN
24  2   2016-11-30     b        5.0
25  2   2016-12-31    NaN       NaN
26  2   2017-01-31    NaN       NaN
27  2   2017-02-28    NaN       NaN
28  2   2017-03-31    NaN       NaN

所需的df

   id      date     compname   fyr
1   1   2016-02-29     a       5.0
2   1   2016-03-31     a       5.0
3   1   2016-04-30     a       5.0
4   1   2016-05-31     a       5.0
5   1   2016-06-30     a       5.0
6   1   2016-07-31     a       5.0
7   1   2016-08-31     a       5.0
8   1   2016-09-30     a       5.0
9   1   2016-10-31     a       5.0
10  1   2016-11-30     a       5.0
11  1   2016-12-31     a       5.0
12  1   2017-01-31     a       5.0
13  1   2017-02-28    NaN      NaN
14  1   2017-03-31    NaN      NaN
15  2   2016-02-29     b       5.0
16  2   2016-03-31     b       5.0
17  2   2016-04-30     b       5.0
18  2   2016-05-31     b       5.0
19  2   2016-06-30     b       5.0
20  2   2016-07-31     b       5.0
21  2   2016-08-31     b       5.0
22  2   2016-09-30     b       5.0
23  2   2016-10-31     b       5.0
24  2   2016-11-30     b       5.0
25  2   2016-12-31     b       5.0
26  2   2017-01-31     b       5.0
27  2   2017-02-28    NaN      NaN
28  2   2017-03-31    NaN      NaN

2 个答案:

答案 0 :(得分:1)

一种方法是先做groupbybfill,然后再做groupbyfillna

df[["compname","fyr"]] = df.groupby("id")["compname","fyr"].bfill()

print (df.groupby("id").apply(lambda d: d.fillna(d.shift(2))))

    id        date compname  fyr
1    1  2016-02-29        a  5.0
2    1  2016-03-31        a  5.0
3    1  2016-04-30        a  5.0
4    1  2016-05-31        a  5.0
5    1  2016-06-30        a  5.0
6    1  2016-07-31        a  5.0
7    1  2016-08-31        a  5.0
8    1  2016-09-30        a  5.0
9    1  2016-10-31        a  5.0
10   1  2016-11-30        a  5.0
11   1  2016-12-31        a  5.0
12   1  2017-01-31        a  5.0
13   1  2017-02-28      NaN  NaN
14   1  2017-03-31      NaN  NaN
15   2  2016-02-29        b  5.0
16   2  2016-03-31        b  5.0
17   2  2016-04-30        b  5.0
18   2  2016-05-31        b  5.0
19   2  2016-06-30        b  5.0
20   2  2016-07-31        b  5.0
21   2  2016-08-31        b  5.0
22   2  2016-09-30        b  5.0
23   2  2016-10-31        b  5.0
24   2  2016-11-30        b  5.0
25   2  2016-12-31        b  5.0
26   2  2017-01-31        b  5.0
27   2  2017-02-28      NaN  NaN
28   2  2017-03-31      NaN  NaN

答案 1 :(得分:1)

如果仅需要每组来回填充,则只需向2个值添加参数@bot.event async def on_ready(): for m in bot.get_all_members(): try: # this can fail if a user has DMs disabled await m.send("Something here") except: pass print("[+] Bot is ready") limitbfill方法中即可。

ffill