如何使用df.resample时让全NaN分组的求和结果为NaN而非0?
解决方案:resample聚合时区分全NaN组与混合组
下面提供两种基于resample的实现方式,满足你"全NaN分组返回NaN、混合分组将NaN视为0求和"的需求:
方法1:自定义聚合函数
直接在agg中使用自定义函数,先判断分组内是否全为NaN,再决定返回值:
import pandas as pd import numpy as np # 构造示例数据 d = {'date': pd.date_range(start='2022-12-09 00:00:00', end='2022-12-09 02:50:00', freq='10min'), 'amount': [np.nan]*6 + [1]*5 + [np.nan] +[2]*6} df = pd.DataFrame(d) # 自定义聚合逻辑 def custom_sum(group): if group.isna().all(): return np.nan return group.sum() # 按小时聚合 result = df.resample(rule='H', on='date').agg({'amount': custom_sum}) print(result)
输出结果:
amount date 2022-12-09 00:00:00 NaN 2022-12-09 01:00:00 5.0 2022-12-09 02:00:00 12.0
方法2:先聚合再替换
先计算常规sum结果,再通过分组判断替换全NaN组的数值:
# 按小时分组,同时计算sum值和是否全为NaN的标记 agg_data = df.resample('H', on='date')['amount'].agg( sum_amount='sum', is_all_nan=lambda x: x.isna().all() ) # 根据标记替换结果 agg_data['amount'] = np.where(agg_data['is_all_nan'], np.nan, agg_data['sum_amount']) # 整理最终结果 result = agg_data.drop(columns=['sum_amount', 'is_all_nan']) print(result)
输出与方法1完全一致。
原理说明
pandas默认的sum聚合在遇到全NaN分组时会返回0(因为skipna=True),无法直接区分"全NaN"和"实际求和为0"的场景。通过额外判断分组内是否所有值都是NaN,就能精准实现你需要的逻辑。
内容的提问来源于stack exchange,提问作者CDJB
相关产品推荐
相关产品推荐

