Python-Polars:如何按气象站分组用前后均值填充缺失值?
按气象站分组填充Polars时间序列缺失值
针对你的需求——按气象站分组,用前后两日均值填充中间缺失的温度值,首尾缺失值用相邻日期数值填充——可以通过Polars的group_by结合map_batches和条件判断实现,具体步骤如下:
完整代码实现
import polars as pl # 示例数据 data = { 'Date': ['2024-01-24', '2024-01-25', '2024-01-26', '2024-01-24', '2024-01-25', '2024-01-26'], 'Weather_Station': ['A', 'A', 'A', 'B', 'B', 'B'], 'Temp': [74, None, 78, None, 65, 78] } # 初始化DataFrame并转换日期类型 df = pl.DataFrame(data).with_columns(pl.col('Date').str.to_date()) # 确保每个站点的时间序列按日期排序(若原始数据无序则必须添加) df = df.sort(['Weather_Station', 'Date']) # 分组填充缺失值 filled_df = df.group_by('Weather_Station', maintain_order=True).agg( pl.col('Date'), pl.col('Temp').map_batches( lambda s: s.fill_null( pl.when(pl.col('Temp').is_null()) # 中间缺失:取前后两日均值 .then( pl.when(pl.col('Temp').shift(1).is_not_null() & pl.col('Temp').shift(-1).is_not_null()) .then((pl.col('Temp').shift(1) + pl.col('Temp').shift(-1)) / 2) # 首行缺失:取后一日数值 .when(pl.col('Temp').shift(1).is_null()) .then(pl.col('Temp').shift(-1)) # 末行缺失:取前一日数值 .when(pl.col('Temp').shift(-1).is_null()) .then(pl.col('Temp').shift(1)) ) ) ).alias('Filled_Temp') ).explode(['Date', 'Filled_Temp']) # 查看结果 print(filled_df)
代码逻辑解释
- 日期类型转换与排序:先将
Date列转为日期格式,并按站点和日期排序,保证每个站点的时间序列连续有序,确保shift操作能正确获取前后日期的数值。 - 分组处理:通过
group_by('Weather_Station')确保每个站点的数据独立处理,不会跨站点借用填充值。 - 缺失值填充规则:
- 对于中间位置的缺失值:同时获取前一日(
shift(1))和后一日(shift(-1))的温度值,计算均值填充。 - 对于首行缺失值:仅存在后一日数据,直接用后一日数值填充。
- 对于末行缺失值:仅存在前一日数据,直接用前一日数值填充。
- 对于中间位置的缺失值:同时获取前一日(
- 展开分组结果:用
explode将分组聚合后的列表型数据还原为原始行结构。
输出结果
运行代码后得到填充后的DataFrame:
shape: (6, 3) ┌──────────────────┬────────────┬─────────────┐ │ Weather_Station ┆ Date ┆ Filled_Temp │ │ --- ┆ --- ┆ --- │ │ str ┆ date ┆ f64 │ ╞══════════════════╪════════════╪═════════════╡ │ A ┆ 2024-01-24 ┆ 74.0 │ │ A ┆ 2024-01-25 ┆ 76.0 │ │ A ┆ 2024-01-26 ┆ 78.0 │ │ B ┆ 2024-01-24 ┆ 65.0 │ │ B ┆ 2024-01-25 ┆ 65.0 │ │ B ┆ 2024-01-26 ┆ 78.0 │ └──────────────────┴────────────┴─────────────┘
内容的提问来源于stack exchange,提问作者ikebeau
相关产品推荐
相关产品推荐

