Pandas分组重采样时返回NaN而非0的实现问题
重采样后空值保留NaN而非0的解决方案
测试数据
import pandas as pd data = {"timestamp": ["2022-12-15 22:00:00", "2022-12-15 22:00:30", "2022-12-15 22:00:47", "2022-12-15 22:00:03", "2022-12-15 22:00:30", "2022-12-15 22:00:43", "2022-12-15 22:00:10", "2022-12-15 22:00:34", "2022-12-15 22:00:59"], "ID": ["A","A","A", "B", "B", "B", "C", "C", "C"], "value": [11, 0, 0, 7, 5, 7, 0, 3.4, 3.4] } df_test = pd.DataFrame(data, columns=["timestamp", "ID", "value"]) df_test["timestamp"] = pd.to_datetime(df_test["timestamp"])
需求
生成新DataFrame,每个ID对应2022-12-15 22:00:00至22:01:00的每一秒数据行(共180行,每个ID60行),匹配原timestamp的行保留value值,其余行设为NaN。
当前问题
使用df_resampled = df_test.groupby("ID").resample("S", on="timestamp").sum().reset_index()时,未匹配到原数据的行被填充为0,不符合需求。
解决方案
方法1:用asfreq()直接生成时间序列
resample().sum()会默认将空值填充为0,改用asfreq()可以直接保留NaN,同时保留原数据的value:
df_resampled = df_test.groupby("ID").resample("S", on="timestamp").asfreq().reset_index()
该方法会按每秒频率生成完整时间序列,没有对应原数据的行直接填充NaN,完全符合需求。如果同一ID同一时间戳有多行数据,asfreq()会保留第一行的value。
方法2:选择合适的聚合函数
如果需要对同一时间戳的多行数据做聚合,可使用first()、last()或mean()等函数,这些函数在无数据时会返回NaN,而非0:
# 取每组第一个值 df_resampled = df_test.groupby("ID").resample("S", on="timestamp")["value"].first().reset_index() # 或取每组最后一个值 df_resampled = df_test.groupby("ID").resample("S", on="timestamp")["value"].last().reset_index() # 或计算均值 df_resampled = df_test.groupby("ID").resample("S", on="timestamp")["value"].mean().reset_index()
根据实际业务需求选择对应的聚合方式即可。
方法3:替换结果中的0为NaN(不推荐)
如果一定要使用sum(),可以后续通过索引判断替换无数据的0,但该方法容易误替换原数据中本身存在的0值,仅作参考:
df_resampled = df_test.groupby("ID").resample("S", on="timestamp").sum().reset_index() # 仅替换无对应原数据的0为NaN original_indices = df_test.set_index(["ID", "timestamp"]).index resampled_indices = df_resampled.set_index(["ID", "timestamp"]).index df_resampled.loc[~resampled_indices.isin(original_indices), "value"] = pd.NA
内容的提问来源于stack exchange,提问作者andKaae
相关产品推荐
相关产品推荐

