如何在带Datetime索引的Pandas DataFrame中按指定时段累加降水量
气象数据时段降水量计算解决方案
问题描述
我有小时级和30分钟级的气象数据,每日13:00采样温度、湿度用于后续分析,这部分操作较为简单。但需要计算当日13:00时过去24小时(前一日13:30至当日13:00)的降水量总和。尝试了使用pd.Grouper结合offset参数的方法,但无法找到合适的参数实现预期累加,寻求一种与原始数据时间间隔(1小时/30分钟)无关的Datetime方法解决该问题。
原始尝试代码:
import pandas as pd import numpy as np # 生成小时级气象数据示例 np.random.seed(42) date_rng = pd.date_range(start='2023-08-01', end='2023-08-14', freq='H') data = { 'Date_Time': date_rng, 'Temperature_Celsius': np.random.uniform(20, 35, size=len(date_rng)), 'Precipitation_mm': np.random.uniform(0, 5, size=len(date_rng)), 'Humidity_Percentage': np.random.uniform(40, 80, size=len(date_rng)) } weather_df = pd.DataFrame(data) weather_df['Date_Time'] = pd.to_datetime(weather_df['Date_Time']) weather_df.set_index('Date_Time', inplace=True) daily_precip = weather_df['Precipitation_mm'].groupby(pd.Grouper(freq='D', offset='12H')).sum()
解决方案
方法1:时间窗口筛选+聚合求和
核心逻辑是直接针对每个13:00的时间点,划定对应的统计窗口范围,再筛选数据求和。该方法完全不受原始数据时间间隔限制,只要时间索引为datetime类型即可运行。
步骤:
- 提取数据中所有每日13:00的时间点作为目标统计节点
- 对每个目标节点,计算窗口起始时间:当前13:00减去24小时再加30分钟(即前一日13:30)
- 遍历每个窗口,筛选范围内的降水量数据并求和
代码实现:
import pandas as pd import numpy as np # 生成30分钟级示例数据(测试兼容性) np.random.seed(42) date_rng = pd.date_range(start='2023-08-01', end='2023-08-14', freq='30T') data = { 'Date_Time': date_rng, 'Temperature_Celsius': np.random.uniform(20, 35, size=len(date_rng)), 'Precipitation_mm': np.random.uniform(0, 5, size=len(date_rng)), 'Humidity_Percentage': np.random.uniform(40, 80, size=len(date_rng)) } weather_df = pd.DataFrame(data) weather_df['Date_Time'] = pd.to_datetime(weather_df['Date_Time']) weather_df.set_index('Date_Time', inplace=True) # 获取所有每日13:00的时间点 target_times = weather_df.at_time('13:00').index # 逐个窗口计算降水量总和 precip_results = [] for target in target_times: start_time = target - pd.Timedelta(hours=24) + pd.Timedelta(minutes=30) window_precip = weather_df.loc[start_time:target, 'Precipitation_mm'].sum() precip_results.append({'Target_Time': target, 'Past_24h_Precip_mm': window_precip}) # 转换为结果DataFrame daily_precip_df = pd.DataFrame(precip_results).set_index('Target_Time') print(daily_precip_df)
方法2:滚动窗口+边界调整
利用pandas的滚动窗口功能,先计算24小时滚动求和,再通过调整窗口范围排除不需要的时段,最后提取每日13:00的结果。该方法效率更高,适合处理大规模数据。
代码实现:
# 基于已设置时间索引的weather_df # 创建24小时滚动窗口,包含右边界(当前时间),不包含左边界 rolling_precip = weather_df['Precipitation_mm'].rolling( window='24H', closed='right', min_periods=1 ).sum() # 提取每日13:00的滚动求和结果 daily_precip_rolling = rolling_precip.at_time('13:00') # 计算需要排除的时段(前一日13:00-13:30)的降水量 exclude_period = weather_df['Precipitation_mm'].groupby( pd.Grouper(freq='D', offset='12H') ).apply(lambda x: x.between_time('13:00', '13:30').sum()) # 调整结果,得到目标时段的降水量总和 daily_precip_final = daily_precip_rolling.subtract(exclude_period.shift(1), fill_value=0) print(daily_precip_final)
说明
两种方法均兼容任意时间间隔的气象数据,无需针对小时/30分钟级数据做特殊调整。方法1逻辑直观,便于调试;方法2运算效率更高,适合大数据量场景。
内容的提问来源于stack exchange,提问作者Konrad Bauer
相关产品推荐
相关产品推荐

