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