python pandas 在最后一个非 NaN 值处停止 fillna
python pandas stop fillna at last non NaN value
我有一个数据框,其中索引是按日期递增的,列是对变量的观察。阵列是稀疏的。
我的目标是及时向前传播一个已知值来填充 NaN 但我想在最后一个非 NaN 值处停止,因为最后一个值表示变量的“死亡”。
例如对于数据集
a
b
c
2020-01-01
NaN
11
NaN
2020-02-01
1
NaN
NaN
2020-03-01
NaN
NaN
14
2020-04-01
2
NaN
NaN
2020-05-01
NaN
NaN
NaN
2020-06-01
NaN
NaN
15
2020-07-01
3
NaN
NaN
2020-08-01
NaN
NaN
NaN
我要输出
a
b
c
2020-01-01
NaN
11
NaN
2020-02-01
1
NaN
NaN
2020-03-01
1
NaN
14
2020-04-01
2
NaN
14
2020-05-01
2
NaN
14
2020-06-01
2
NaN
15
2020-07-01
3
NaN
NaN
2020-08-01
NaN
NaN
NaN
我可以使用 df.notna()[::-1].idxmax()
识别最后一次观察的索引,但无法弄清楚如何使用它来限制 fillna
函数
如果有任何建议,我将不胜感激。非常感谢
使用 DataFrame.where
通过掩码进行前向填充 - 通过向后填充仅测试非缺失值:
df = df.where(df.bfill().isna(), df.ffill())
print (df)
a b c
2020-01-01 NaN 11.0 NaN
2020-02-01 1.0 NaN NaN
2020-03-01 1.0 NaN 14.0
2020-04-01 2.0 NaN 14.0
2020-05-01 2.0 NaN 14.0
2020-06-01 2.0 NaN 15.0
2020-07-01 3.0 NaN NaN
2020-08-01 NaN NaN NaN
如果通过广播比较 Series 转换为 numpy 数组,也应该使用您的解决方案:
mask = df.notna()[::-1].idxmax().to_numpy() < df.index.to_numpy()[:, None]
df = df.where(mask, df.ffill())
print (df)
a b c
2020-01-01 NaN 11.0 NaN
2020-02-01 1.0 NaN NaN
2020-03-01 1.0 NaN 14.0
2020-04-01 2.0 NaN 14.0
2020-05-01 2.0 NaN 14.0
2020-06-01 2.0 NaN 15.0
2020-07-01 3.0 NaN NaN
2020-08-01 NaN NaN NaN
您可以使用专门为此设计的 Series.last_valid_index
(return 最后一个 non-NA/null 值的索引),直到 ffill
为止:
假设您的数据集名为 df
:
df.apply(lambda x: x.loc[:x.last_valid_index()].ffill())
index a b c
0 2020-01-01 NaN 11.00 NaN
1 2020-02-01 1.00 NaN NaN
2 2020-03-01 1.00 NaN 14.00
3 2020-04-01 2.00 NaN 14.00
4 2020-05-01 2.00 NaN 14.00
5 2020-06-01 2.00 NaN 15.00
6 2020-07-01 3.00 NaN NaN
7 2020-08-01 NaN NaN NaN
更多相关信息:
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.last_valid_index.html
我有一个数据框,其中索引是按日期递增的,列是对变量的观察。阵列是稀疏的。 我的目标是及时向前传播一个已知值来填充 NaN 但我想在最后一个非 NaN 值处停止,因为最后一个值表示变量的“死亡”。
例如对于数据集
a | b | c | |
---|---|---|---|
2020-01-01 | NaN | 11 | NaN |
2020-02-01 | 1 | NaN | NaN |
2020-03-01 | NaN | NaN | 14 |
2020-04-01 | 2 | NaN | NaN |
2020-05-01 | NaN | NaN | NaN |
2020-06-01 | NaN | NaN | 15 |
2020-07-01 | 3 | NaN | NaN |
2020-08-01 | NaN | NaN | NaN |
我要输出
a | b | c | |
---|---|---|---|
2020-01-01 | NaN | 11 | NaN |
2020-02-01 | 1 | NaN | NaN |
2020-03-01 | 1 | NaN | 14 |
2020-04-01 | 2 | NaN | 14 |
2020-05-01 | 2 | NaN | 14 |
2020-06-01 | 2 | NaN | 15 |
2020-07-01 | 3 | NaN | NaN |
2020-08-01 | NaN | NaN | NaN |
我可以使用 df.notna()[::-1].idxmax()
识别最后一次观察的索引,但无法弄清楚如何使用它来限制 fillna
函数
如果有任何建议,我将不胜感激。非常感谢
使用 DataFrame.where
通过掩码进行前向填充 - 通过向后填充仅测试非缺失值:
df = df.where(df.bfill().isna(), df.ffill())
print (df)
a b c
2020-01-01 NaN 11.0 NaN
2020-02-01 1.0 NaN NaN
2020-03-01 1.0 NaN 14.0
2020-04-01 2.0 NaN 14.0
2020-05-01 2.0 NaN 14.0
2020-06-01 2.0 NaN 15.0
2020-07-01 3.0 NaN NaN
2020-08-01 NaN NaN NaN
如果通过广播比较 Series 转换为 numpy 数组,也应该使用您的解决方案:
mask = df.notna()[::-1].idxmax().to_numpy() < df.index.to_numpy()[:, None]
df = df.where(mask, df.ffill())
print (df)
a b c
2020-01-01 NaN 11.0 NaN
2020-02-01 1.0 NaN NaN
2020-03-01 1.0 NaN 14.0
2020-04-01 2.0 NaN 14.0
2020-05-01 2.0 NaN 14.0
2020-06-01 2.0 NaN 15.0
2020-07-01 3.0 NaN NaN
2020-08-01 NaN NaN NaN
您可以使用专门为此设计的 Series.last_valid_index
(return 最后一个 non-NA/null 值的索引),直到 ffill
为止:
假设您的数据集名为 df
:
df.apply(lambda x: x.loc[:x.last_valid_index()].ffill())
index a b c
0 2020-01-01 NaN 11.00 NaN
1 2020-02-01 1.00 NaN NaN
2 2020-03-01 1.00 NaN 14.00
3 2020-04-01 2.00 NaN 14.00
4 2020-05-01 2.00 NaN 14.00
5 2020-06-01 2.00 NaN 15.00
6 2020-07-01 3.00 NaN NaN
7 2020-08-01 NaN NaN NaN
更多相关信息:
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.last_valid_index.html