基于最小观测数要求的Pandas时间序列重采样技术咨询
Pandas重采样月度数据:基于最小观测数阈值保留结果
嘿,刚好碰到过类似的需求,咱们可以用Pandas的重采样工具结合简单的逻辑判断来实现,完全符合你要的「至少90%日度数据存在才输出求和结果」的要求。
核心思路
我们需要对每个月度的日度数据做两个关键判断:
- 该月非缺失数据的占比是否≥90%
- 如果满足条件,返回该月的求和值;否则返回NaN
下面给两种实操方法,你可以根据自己的习惯选择:
方法一:自定义聚合函数(紧凑版)
直接在resample()后用apply()传入自定义函数,在函数里完成占比判断和求和:
import pandas as pd import numpy as np # 模拟你的日度数据(带少量NaN的1月、几乎全NaN的10月) date_range = pd.date_range(start='2023-01-01', end='2023-10-31', freq='D') data = np.random.randn(len(date_range)) # 1月加3个NaN(占比≈90.3%,刚好满足阈值) data[:3] = np.nan # 10月只留2个有效数据(占比≈6.5%,不满足阈值) data[-30:] = np.nan data[-15] = 4.2 data[-5] = 3.7 df = pd.DataFrame({'daily_value': data}, index=date_range) # 自定义聚合函数 def sum_with_min_threshold(x): # 计算非缺失数据的占比 valid_ratio = x.notna().mean() # 满足阈值则返回求和,否则返回NaN return x.sum() if valid_ratio >= 0.9 else np.nan # 执行月度重采样 monthly_result = df['daily_value'].resample('M').apply(sum_with_min_threshold)
运行后,1月的结果会是有效求和值,10月的结果则为NaN,完全符合你的预期。
方法二:分步计算(直观版)
如果觉得自定义函数不够直观,可以拆分步骤:先算月度求和、再算有效数据占比,最后用where()过滤结果:
# 1. 计算月度求和值 monthly_sum = df['daily_value'].resample('M').sum() # 2. 计算每个月的有效数据数量 monthly_valid_count = df['daily_value'].resample('M').count() # 3. 获取每个月的总天数(Pandas自动处理不同月份的天数差异) monthly_total_days = monthly_sum.index.days_in_month # 4. 计算有效数据占比 valid_ratio = monthly_valid_count / monthly_total_days # 5. 过滤结果:占比≥90%保留求和,否则设为NaN monthly_result_filtered = monthly_sum.where(valid_ratio >= 0.9)
这种方法每一步都清晰,方便你调试中间结果,比如查看每个月的有效数据占比是否正确。
注意点
- 用
index.days_in_month能准确获取每个月的实际天数,避免手动计算出错(比如2月的28/29天、31天的大月等) - 如果你的数据是多列,只需要把列名替换成对应的即可,或者对整个DataFrame应用聚合逻辑
内容的提问来源于stack exchange,提问作者EHB




