水位、流量、含沙量——水文数据的特点是时间序列长、缺测多、单位杂。这里攒了 10 个我反复使用的 pandas 片段,可以直接抄。

1-3:读入与清洗

# 1. 缺测值统一处理(水文常用 -9998 表示缺测)
df = pd.read_csv("stage.csv", na_values=[-9998, -9999])

# 2. 时间列直接转索引,一步到位
df["tm"] = pd.to_datetime(df["tm"])
df = df.set_index("tm").sort_index()

# 3. 去重:同一时刻只保留最后一条
df = df[~df.index.duplicated(keep="last")]

4-6:重采样与滑动

# 4. 小时值转日均值
daily = df["z"].resample("D").mean()

# 5. 24 小时滑动平均(看水位趋势)
df["z_ma24"] = df["z"].rolling(24, min_periods=18).mean()

# 6. 涨率:一小时水位差(涨/落判断)
df["rise_rate"] = df["z"].diff()

7-10:判定与输出

# 7. 超警戒水位标记
df["over_warn"] = df["z"] > df["warn_z"]

# 8. 找出连续 N 小时超警戒的时段
grp = (df["over_warn"] != df["over_warn"].shift()).cumsum()
runs = df[df["over_warn"]].groupby(grp)

# 9. 缺测率统计
miss = df["z"].isna().resample("M").mean()

# 10. 导出_excel 多表
with pd.ExcelWriter("out.xlsx") as w:
    df.to_excel(w, sheet_name="hourly")
    daily.to_excel(w, sheet_name="daily")
经验:min_periods 一定要设,否则数据缺测多的时段滑动窗口会整段变 NaN。