Pandas:用下一个非 NaN 填充 NaNs / # 个连续的 NaNs
Pandas: Fill NaNs with next non-NaN / # consecutive NaNs
我正在寻找一个 pandas 系列,并用下一个数值的平均值填充 NaN
,其中:average = next numerical value / (# consecutive NaNs + 1)
到目前为止,这是我的代码,我只是不知道如何在 num
中的 NaN
之间划分 filler
列(以及下一个数值) ]:
import pandas as pd
dates = pd.date_range(start = '1/1/2016',end = '1/12/2016', freq = 'D')
nums = [10, 12, None, None, 39, 10, 11, None, None, None, None, 60]
df = pd.DataFrame({
'date':dates,
'num':nums
})
df['filler'] = df['num'].fillna(method = 'bfill')
当前输出:
date num filler
0 2016-01-01 10.0 10.0
1 2016-01-02 12.0 12.0
2 2016-01-03 NaN 39.0
3 2016-01-04 NaN 39.0
4 2016-01-05 39.0 39.0
5 2016-01-06 10.0 10.0
6 2016-01-07 11.0 11.0
7 2016-01-08 NaN 60.0
8 2016-01-09 NaN 60.0
9 2016-01-10 NaN 60.0
10 2016-01-11 NaN 60.0
11 2016-01-12 60.0 60.0
期望的输出:
date num
0 2016-01-01 10.0
1 2016-01-02 12.0
2 2016-01-03 13.0
3 2016-01-04 13.0
4 2016-01-05 13.0
5 2016-01-06 10.0
6 2016-01-07 11.0
7 2016-01-08 12.0
8 2016-01-09 12.0
9 2016-01-10 12.0
10 2016-01-11 12.0
11 2016-01-12 12.0
- 对
notnull
进行反向 cumsum
- 将其用于
groupby
和 transform
以及 mean
csum = df.num.notnull()[::-1].cumsum()
filler = df.num.fillna(0).groupby(csum).transform('mean')
df.assign(filler=filler)
date num filler
0 2016-01-01 10.0 10.0
1 2016-01-02 12.0 12.0
2 2016-01-03 NaN 13.0
3 2016-01-04 NaN 13.0
4 2016-01-05 39.0 13.0
5 2016-01-06 10.0 10.0
6 2016-01-07 11.0 11.0
7 2016-01-08 NaN 12.0
8 2016-01-09 NaN 12.0
9 2016-01-10 NaN 12.0
10 2016-01-11 NaN 12.0
11 2016-01-12 60.0 12.0
工作原理
df.num.notnull().cumsum()
是查找连续空值组的标准技术。但是,我希望我的组以下一个数值结束。所以我颠倒了系列然后 cumsum
'd.
- 我希望我的平均值包括空值的数量。最简单的方法是用零填充并对我刚刚创建的组取一个正常平均值。
transform
在现有索引中广播
assign
新专栏。尽管已经颠倒了系列,但该指数将像魔术一样重新排列。可以使用 loc
,但会覆盖现有的 df
。如果他们愿意,我会让 OP 决定覆盖。
我正在寻找一个 pandas 系列,并用下一个数值的平均值填充 NaN
,其中:average = next numerical value / (# consecutive NaNs + 1)
到目前为止,这是我的代码,我只是不知道如何在 num
中的 NaN
之间划分 filler
列(以及下一个数值) ]:
import pandas as pd
dates = pd.date_range(start = '1/1/2016',end = '1/12/2016', freq = 'D')
nums = [10, 12, None, None, 39, 10, 11, None, None, None, None, 60]
df = pd.DataFrame({
'date':dates,
'num':nums
})
df['filler'] = df['num'].fillna(method = 'bfill')
当前输出:
date num filler
0 2016-01-01 10.0 10.0
1 2016-01-02 12.0 12.0
2 2016-01-03 NaN 39.0
3 2016-01-04 NaN 39.0
4 2016-01-05 39.0 39.0
5 2016-01-06 10.0 10.0
6 2016-01-07 11.0 11.0
7 2016-01-08 NaN 60.0
8 2016-01-09 NaN 60.0
9 2016-01-10 NaN 60.0
10 2016-01-11 NaN 60.0
11 2016-01-12 60.0 60.0
期望的输出:
date num
0 2016-01-01 10.0
1 2016-01-02 12.0
2 2016-01-03 13.0
3 2016-01-04 13.0
4 2016-01-05 13.0
5 2016-01-06 10.0
6 2016-01-07 11.0
7 2016-01-08 12.0
8 2016-01-09 12.0
9 2016-01-10 12.0
10 2016-01-11 12.0
11 2016-01-12 12.0
- 对
notnull
进行反向 - 将其用于
groupby
和transform
以及mean
cumsum
csum = df.num.notnull()[::-1].cumsum()
filler = df.num.fillna(0).groupby(csum).transform('mean')
df.assign(filler=filler)
date num filler
0 2016-01-01 10.0 10.0
1 2016-01-02 12.0 12.0
2 2016-01-03 NaN 13.0
3 2016-01-04 NaN 13.0
4 2016-01-05 39.0 13.0
5 2016-01-06 10.0 10.0
6 2016-01-07 11.0 11.0
7 2016-01-08 NaN 12.0
8 2016-01-09 NaN 12.0
9 2016-01-10 NaN 12.0
10 2016-01-11 NaN 12.0
11 2016-01-12 60.0 12.0
工作原理
df.num.notnull().cumsum()
是查找连续空值组的标准技术。但是,我希望我的组以下一个数值结束。所以我颠倒了系列然后cumsum
'd.- 我希望我的平均值包括空值的数量。最简单的方法是用零填充并对我刚刚创建的组取一个正常平均值。
transform
在现有索引中广播assign
新专栏。尽管已经颠倒了系列,但该指数将像魔术一样重新排列。可以使用loc
,但会覆盖现有的df
。如果他们愿意,我会让 OP 决定覆盖。