推荐使用 resample(...).last() 或 resample(...).apply(lambda x: x.iloc[-1]) 保留每组最后一行完整数据;前者取各列最后一个非空值,后者严格取原始索引末位整行,均需确保时间索引已排序且无重复。

在 pandas 中对时间序列进行 resample 时,默认会聚合(如取均值、求和等),原始的非时间列(如 ID、标签、状态等)通常会丢失或无法直接保留。若想在 resample 后**保留原始最后一行对应的所有其他列值**(即按时间分组后,每组取时间上最晚那条记录的完整行,而非仅对数值列聚合),推荐使用 resample(...).last() 或更稳妥的 resample(...).apply(lambda x: x.iloc[-1])。
用 .last() 直接获取每组最后一条记录
.last() 是 resample 的内置方法,它对每组内各列分别取**最后一个非空值**(注意:不是索引最大的行,而是按时间顺序排好后,最后一个有效值)。前提是你的 DatetimeIndex 已排序且无重复时间戳(否则行为可能不符合预期)。
df_resampled = df.resample('D').last()✅ 优点:简洁、高效。
⚠️ 注意:对非数值列(如字符串、类别型)也适用;但如果某列在该组内全为 NaN,则结果也为 NaN。
用 .apply(lambda x: x.iloc[-1]) 确保取原始最后一行完整数据
当需要严格保证取的是**原始 DataFrame 中该组里索引位置最靠后(即时间戳最大)的那一整行**(包括所有列,不管是否为空),应使用 apply + iloc[-1]:
df_resampled = df.resample('D').apply(lambda x: x.iloc[-1])✅ 优点:100% 取原始最后一行,不跳过 NaN,保留全部列结构。
⚠️ 注意:要求每组至少有一行(否则报错),可加 dropna=False 并配合异常处理;若存在多条相同时间戳的记录,iloc[-1] 取的是它们中在原始顺序里排最后的那个。
确保时间索引正确且已排序
resample 行为依赖 DatetimeIndex 的顺序。如果时间列是普通列,需先设为索引并排序:
df = df.set_index('time_col').sort_index()- 若时间列含时区,建议统一转为 UTC 或无时区(
dt.tz_localize(None)或dt.tz_convert(None)),避免 resample 出错 - 检查是否有重复时间戳:
df.index.duplicated().any(),如有,考虑先去重或用groupby(..., dropna=False)预处理
补充:想保留特定列(如 ID)而不参与聚合?
如果只想保留某几列(比如 'id', 'status'),又不想让它们被 .last() 影响(例如怕 status 被误填 NaN),可先分离再合并:
numeric_cols = df.select_dtypes(include='number').columns other_cols = ['id', 'status']对数值列 resample 求和/均值,对其他列取 last
resampled_numeric = df[numeric_cols].resample('D').sum() resampled_other = df[other_cols].resample('D').last()
df_resampled = pd.concat([resampled_numeric, resampled_other], axis=1)










