如何按ID分组并依据datetime列倒序获取多列首个非空值?
按ID分组提取倒序后首个非空值的解决方案
原始数据
id ts site type 0 111 2022-07-25 19:07:00.938365 A NaN 1 111 2022-07-25 19:07:00.938371 NaN 1.0 2 222 2022-07-25 19:07:00.938372 NaN NaN 3 222 2022-07-25 19:07:00.938373 NaN 2.0 4 222 2022-07-25 19:07:00.938374 C 1.0
需求
按id分组,每组内按ts倒序排列,提取site和type列的首个非空值,预期输出:
id site type 0 111 A 1.0 1 222 C 1.0
错误尝试
尝试1
df_grouped = df.sort_values(by="ts", ascending=False).groupby("id").ffill().first()
触发报错:
TypeError: first() missing 1 required positional argument: 'offset'
原因:first()方法在DataFrameGroupBy对象后需要传入时间偏移参数,并非用于取首行的方法。
尝试2
df_grouped[["site", "type"]].apply(lambda x: x.first_valid_index()).reset_index()
输出不符合预期:
index 0 0 site 0 1 screen_type 0
原因:该代码仅获取了整个DataFrame中列的首个非空索引,未按分组处理。
正确实现代码
# 按id分组、ts倒序排序 df_sorted = df.sort_values(by=["id", "ts"], ascending=[True, False]) # 分组后提取各列首个非空值 result = df_sorted.groupby("id").agg( site=("site", lambda x: x.dropna().iloc[0] if not x.dropna().empty else None), type=("type", lambda x: x.dropna().iloc[0] if not x.dropna().empty else None) ).reset_index()
代码说明
- 排序:先按
id升序、ts降序排序,确保每组内时间最新的记录排在最前面 - 分组聚合:对每个分组的
site和type列,先剔除空值,再取第一个元素(即倒序后的首个非空值) - 重置索引:将
id从分组索引转换为普通列,匹配预期输出格式
执行后得到结果:
id site type 0 111 A 1.0 1 222 C 1.0
内容的提问来源于stack exchange,提问作者anajbellini
相关产品推荐
相关产品推荐

