You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用一行代码对DataFrame按列向前填充至各列最后有效索引

一行代码实现Pandas DataFrame的限定前向填充

问题说明

现有如下Pandas DataFrame:

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'col1': [100, np.nan, np.nan, 100, np.nan, np.nan],
    'col2': [np.nan, 100, np.nan, np.nan, 100, np.nan]
})

输出结果:

col1   col2
0  100.0   NaN
1   NaN  100.0
2   NaN   NaN
3  100.0   NaN
4   NaN  100.0
5   NaN   NaN

需要将其转换为目标格式:

col1   col2
0  100.0   NaN
1  100.0  100.0
2  100.0  100.0
3  100.0  100.0
4   NaN  100.0
5   NaN   NaN

当前实现是逐列应用自定义方法:

def ffill_last_valid(s):
    last_valid = s.last_valid_index()
    s = s.ffill()
    s[s.index > last_valid] = np.nan
    return s

df.apply(ffill_last_valid)

以下提供两种一行代码的简洁实现方式:

实现方式一:基于布尔矩阵过滤

df.ffill().where(df.notna().cummax().iloc[::-1].cummax().iloc[::-1])

原理拆解

  1. df.ffill():先对整个DataFrame执行前向填充,得到所有NaN被前置有效值填充后的临时结果。
  2. df.notna().cummax():生成布尔矩阵,标记从第0行到当前行是否出现过有效值(一旦出现有效值,后续行均为True)。
  3. .iloc[::-1].cummax().iloc[::-1]:将布尔矩阵反转后做累积最大值,再反转回来,得到的矩阵会标记当前行到最后一行是否存在有效值——只有该区间内有有效值的位置,才保留前向填充结果。
  4. .where():用上述布尔矩阵过滤前向填充结果,不符合条件的位置重置为NaN,完全匹配需求。

实现方式二:基于列最后有效索引判断

df.ffill().mask(df.apply(lambda s: s.index > s.last_valid_index()))

原理拆解

  1. df.apply(lambda s: s.index > s.last_valid_index()):逐列生成布尔序列,标记哪些行的索引超过了该列最后一个有效值的索引。
  2. .mask():将这些标记为True的位置(即超过最后有效值的行)重新设为NaN,逻辑和自定义函数完全一致,但写法更紧凑。

内容的提问来源于stack exchange,提问作者data-monkey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 06:15:46