You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用正弦/线性函数填充Pandas列?潮汐极值列补全需求

用自定义函数填充潮汐水位缺失值的实现方案

嘿,这个需求我之前处理过类似的场景,用Pandas就能轻松搞定!核心思路是先定位你的潮汐峰值(非缺失值的行),把相邻峰值之间的缺失区间分组,再用你想要的线性/正弦函数填充每个区间。下面给你一步步拆解:

1. 标记并提取峰值位置

首先得把所有的潮汐峰值(非缺失的水位值)找出来,给它们做个标记,方便后续分组:

import pandas as pd
import numpy as np

# 假设你的DataFrame叫df,水位列是water_level
df['is_peak'] = df['water_level'].notna()

# 提取所有峰值的索引和对应水位值,方便后续参考
peaks = df[df['is_peak']][['water_level']].reset_index()

2. 为缺失区间分配分组ID

接下来要给每一段缺失值区间分配一个唯一的分组ID,这样我们就知道每个缺失段属于哪两个峰值之间:

# 每遇到一个峰值,分组ID就加1,这样相邻峰值之间的缺失值会被分到同一个组里
df['group_id'] = df['is_peak'].cumsum()

# 如果你DataFrame开头有缺失值(第一个行就是空的),可以选择丢弃这段或者用第一个峰值填充,这里先处理中间的有效区间
df = df[df['group_id'] != 0]

3. 自定义填充函数(线性/正弦示例)

现在就可以针对每个分组,用你想要的函数填充缺失值了,这里给你两个最常用的实现:

线性插值填充(简单直接)

如果想要最基础的直线填充,用线性插值就行:

def linear_fill(group):
    # 获取当前分组的起始和结束峰值
    start_val = group['water_level'].dropna().iloc[0]
    end_val = group['water_level'].dropna().iloc[-1]
    # 生成从start到end的线性序列,刚好填满整个分组
    group['water_level'] = np.linspace(start_val, end_val, len(group))
    return group

# 对每个分组应用线性填充
df_filled_linear = df.groupby('group_id').apply(linear_fill)

正弦函数填充(贴合潮汐特性)

潮汐变化更接近正弦曲线,用正弦函数填充会更符合实际潮汐的波动规律:

def sine_fill(group):
    start_val = group['water_level'].dropna().iloc[0]
    end_val = group['water_level'].dropna().iloc[-1]
    # 计算两个峰值的差值和中间值
    peak_diff = end_val - start_val
    mid_level = (start_val + end_val) / 2
    # 生成0到π的正弦曲线(刚好覆盖从一个峰值到另一个峰值的半周期)
    x = np.linspace(0, np.pi, len(group))
    # 调整正弦曲线的幅度和偏移,让它刚好连接两个峰值
    group['water_level'] = mid_level + (peak_diff / 2) * np.cos(x)
    return group

# 应用正弦填充
df_filled_sine = df.groupby('group_id').apply(sine_fill)

4. 处理特殊情况(可选)

  • 如果DataFrame开头有缺失值:可以用df['water_level'].bfill()把第一个峰值向前填充,或者直接删除这段数据
  • 如果DataFrame结尾有缺失值:用df['water_level'].ffill()把最后一个峰值向后填充,或者删除
  • 如果有连续的峰值(两个非缺失值相邻):分组后会自动跳过,不需要填充

5. 验证填充效果

最后可以画个图看看填充的结果对不对:

import matplotlib.pyplot as plt

plt.figure(figsize=(12, 6))
plt.plot(df_filled_sine.index, df_filled_sine['water_level'], label='正弦填充结果')
plt.scatter(peaks['index'], peaks['water_level'], color='red', s=50, label='原始潮汐峰值')
plt.legend()
plt.title('潮汐水位缺失值填充效果')
plt.show()

你还可以根据实际潮汐的周期调整正弦函数的参数,比如把np.pi改成2*np.pi来模拟完整周期,或者调整幅度让填充更贴合你的数据~

内容的提问来源于stack exchange,提问作者Borja Fernández Antelo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:42:56