如何在Pandas的groupby()中获取分组的最后一条记录(含空值)
分组获取DataFrame每组最后一条完整记录的高效实现
当你需要按student分组,获取每组时间戳最晚的完整记录(无论字段是否为空)时,以下是几种高效且符合需求的实现方式:
最优方案:groupby().tail(1)
直接使用pandas内置的tail(1)方法,它会提取每组的最后一行完整记录,保留所有字段的原始值(包括NaN),且性能远优于apply:
import pandas as pd import numpy as np # 构造示例数据并按时间戳排序 df = pd.DataFrame([["A",2,3],["B",5,6],["A",np.NaN,4]], columns=["student", "value_a", "timestamp"]).sort_values("timestamp") # 获取每组最后一条完整记录 result = df.groupby("student").tail(1)
执行结果:
student value_a timestamp 2 A NaN 4 1 B 5.0 6
优势:
- 完全匹配需求:保留组内最后一行的所有字段值,包括空值
- 性能高效:属于pandas向量化操作,避免了
apply的逐组循环,大数据集下差距明显
备选方案:基于idxmax取最大时间戳对应行
如果需要明确基于timestamp的最大值来取行,可以用idxmax获取每组最大时间戳的索引,再通过loc提取对应行:
# 获取每组timestamp最大的行索引 max_timestamp_idx = df.groupby("student")["timestamp"].idxmax() # 提取对应记录 result = df.loc[max_timestamp_idx]
这个方法效率同样很高,适合需要精准基于某列极值取行的场景。
为什么不推荐以下方法?
groupby().last():每个字段独立取组内最后一个非空值,导致不同字段可能来自组内不同行(比如示例中student=A的value_a取了第一行的2.0,而非最后一行的NaN),不符合“取完整最后一条记录”的需求。groupby().apply(lambda r: r.iloc[-1]):本质是逐组循环处理,代码冗余且性能极差,大数据集下会显著拖慢运行速度。
内容的提问来源于stack exchange,提问作者YGA
相关产品推荐
相关产品推荐

