如何获取列为日期的Pandas DataFrame每行最后非NaN值?
获取Pandas DataFrame每行的最后一个非NaN值
没问题,这个需求在Pandas里有几种实用的解决办法,我结合你的场景(存在日期列,每行对应独立时间序列)给你详细拆解:
核心思路
我们需要针对每行,从右往左定位第一个非NaN的数值。首先要注意先排除日期列,只处理时间序列的数值列。
方法一:向量化操作(推荐大数据量)
这种方法效率最高,用向量化方式处理,避免逐行循环带来的性能损耗:
import pandas as pd import numpy as np # 先构造一个示例DataFrame模拟你的数据结构 df = pd.DataFrame({ '日期': ['2023-01-01', '2023-01-02', '2023-01-03'], '时段1': [12, np.nan, 34], '时段2': [23, 45, np.nan], '时段3': [np.nan, 56, 67] }) # 1. 提取数值列(排除日期列) numeric_df = df.drop('日期', axis=1) # 2. 反转列顺序 → 从左到右填充NaN(等价于原行从右到左找第一个非NaN)→ 取第一列即为目标值 last_non_nan_values = numeric_df.iloc[:, ::-1].bfill(axis=1).iloc[:, 0] # 3. 将结果与日期列合并成新的DataFrame result_df = df[['日期']].assign(最后一个非NaN值=last_non_nan_values) print(result_df)
运行后输出:
日期 最后一个非NaN值 0 2023-01-01 23.0 1 2023-01-02 56.0 2 2023-01-03 67.0
方法二:apply逐行处理(小数据量友好,代码直观)
如果你的数据量不大,用apply写起来更直观,逻辑一目了然:
# 同样先提取数值列 numeric_df = df.drop('日期', axis=1) # 逐行处理:删除NaN后取最后一个值,若整行都是NaN则返回NaN last_non_nan_values = numeric_df.apply( lambda row: row.dropna().iloc[-1] if not row.dropna().empty else np.nan, axis=1 ) # 合并结果 result_df = df[['日期']].assign(最后一个非NaN值=last_non_nan_values)
注意点
- 如果某一行的数值列全是NaN,两种方法都会返回
NaN,你可以根据需求用fillna()替换成默认值(比如0)。 - 确保
日期列是唯一的非数值列,如果还有其他非数值列,需要一并排除在numeric_df之外。
内容的提问来源于stack exchange,提问作者Mustard Tiger
相关产品推荐
相关产品推荐

