如何从Pandas DataFrame中提取每个分组各字段的最新可用记录
实现方法
首先需要确保数据按name和Year升序排序,保证每个name分组内的行按时间从早到晚排列,后续才能正确取到最新的有效记录。
方法1:使用groupby + last()(最简单)
Pandas的GroupBy.last()方法会自动跳过空值,返回每个分组对应列的最后一个非空值,直接适配你的需求:
import pandas as pd import numpy as np # 你的原始数据构造代码 d = {'name': ['a', 'a','a','b','b','b','c','c','c'], 'Year': ['2000', '2010', '2020', '2000', '2010', '2020', '2000', '2010', '2020'], 'v1': [np.NaN, np.NaN, np.NaN, 41, 51, 61, 71, 81, 91], 'v2': [12, 22, 32, np.NaN, 52, np.NaN, 72, 82, 92], 'v3': [13, 23, 33, 43, 53, 63, np.NaN, 83, np.NaN]} df = pd.DataFrame(d) # 核心逻辑 # 先按name和年份排序,原数据已经是有序的,若原始数据无序必须加这一步 df_sorted = df.sort_values(['name', 'Year']) # 分组取各列最后一个非空值 res = df_sorted.groupby('name')[['v1', 'v2', 'v3']].agg('last').reset_index() print(res)
运行后输出完全符合你的预期:
name v1 v2 v3 0 a NaN 32 33.0 1 b 61.0 52 63.0 2 c 91.0 92 83.0
方法2:自定义apply逻辑(兼容性更强)
如果需要更灵活的控制规则,可以用分组+前向填充的方式实现:
def get_latest(group): # 前向填充空值,用最近的有效值覆盖后续空值 filled = group[['v1', 'v2', 'v3']].ffill() # 取最后一行就是各字段最新有效值 return filled.iloc[-1] res = df.sort_values(['name', 'Year']).groupby('name', group_keys=False).apply(get_latest).reset_index()
内容的提问来源于stack exchange,提问作者A A
相关产品推荐
相关产品推荐

