pastas
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePastas - Groundwater Time Series Analysis
Pastas - 地下水时间序列分析
Quick Reference
快速参考
python
import pastas as ps
import pandas as pdpython
import pastas as ps
import pandas as pdLoad data
Load data
head = pd.read_csv('well.csv', index_col=0, parse_dates=True).squeeze()
precip = pd.read_csv('precip.csv', index_col=0, parse_dates=True).squeeze()
evap = pd.read_csv('evap.csv', index_col=0, parse_dates=True).squeeze()
head = pd.read_csv('well.csv', index_col=0, parse_dates=True).squeeze()
precip = pd.read_csv('precip.csv', index_col=0, parse_dates=True).squeeze()
evap = pd.read_csv('evap.csv', index_col=0, parse_dates=True).squeeze()
Create model
Create model
ml = ps.Model(head, name='Well_001')
ml = ps.Model(head, name='Well_001')
Add recharge stress
Add recharge stress
sm = ps.RechargeModel(precip, evap, rfunc=ps.Gamma(), name='recharge')
ml.add_stressmodel(sm)
sm = ps.RechargeModel(precip, evap, rfunc=ps.Gamma(), name='recharge')
ml.add_stressmodel(sm)
Solve and plot
Solve and plot
ml.solve()
ml.plot()
undefinedml.solve()
ml.plot()
undefinedKey Classes
核心类
| Class | Purpose |
|---|---|
| Main model container |
| Response to external stress (pumping, river) |
| Recharge from precipitation minus evaporation |
| Gamma distribution response function |
| Simple exponential response function |
| 类 | 用途 |
|---|---|
| 主模型容器 |
| 对外部应力(抽水、河流)的响应 |
| 降水减蒸发的补给量 |
| 伽马分布响应函数 |
| 简单指数响应函数 |
Essential Operations
核心操作
Create and Solve Model
创建并求解模型
python
ml = ps.Model(head, name='well')
ml.add_stressmodel(ps.RechargeModel(precip, evap, rfunc=ps.Gamma(), name='recharge'))
ml.solve()python
ml = ps.Model(head, name='well')
ml.add_stressmodel(ps.RechargeModel(precip, evap, rfunc=ps.Gamma(), name='recharge'))
ml.solve()Add Pumping Well
添加抽水井
python
pumping = pd.read_csv('pumping.csv', index_col=0, parse_dates=True).squeeze()
ml.add_stressmodel(ps.StressModel(pumping, rfunc=ps.Hantush(),
name='pumping', up=False)) # up=False for drawdownpython
pumping = pd.read_csv('pumping.csv', index_col=0, parse_dates=True).squeeze()
ml.add_stressmodel(ps.StressModel(pumping, rfunc=ps.Hantush(),
name='pumping', up=False)) # up=False代表水位下降Model Diagnostics
模型诊断
python
print(f"EVP: {ml.stats.evp():.1f}%") # Explained variance
print(f"RMSE: {ml.stats.rmse():.3f} m") # Root mean square error
print(f"AIC: {ml.stats.aic():.1f}") # Model selection criterion
ml.plots.diagnostics() # Diagnostic plots
ml.plots.acf() # Autocorrelationpython
print(f"EVP: {ml.stats.evp():.1f}%") # 解释方差百分比
print(f"RMSE: {ml.stats.rmse():.3f} m") # 均方根误差
print(f"AIC: {ml.stats.aic():.1f}") # 模型选择准则
ml.plots.diagnostics() # 诊断图
ml.plots.acf() # 自相关图Get Contributions
获取分量贡献
python
contributions = ml.get_contributions()
for name, contrib in contributions.items():
print(f"{name}: mean={contrib.mean():.2f}")python
contributions = ml.get_contributions()
for name, contrib in contributions.items():
print(f"{name}: 均值={contrib.mean():.2f}")Step and Impulse Response
阶跃与脉冲响应
python
step = ml.get_step_response('recharge') # Step response
block = ml.get_block_response('recharge') # Impulse responsepython
step = ml.get_step_response('recharge') # 阶跃响应
block = ml.get_block_response('recharge') # 脉冲响应Export and Load
导出与加载
python
ml.to_json('model.pas') # Save model
ml_loaded = ps.io.load('model.pas') # Load model
sim = ml.simulate()
sim.to_csv('simulation.csv') # Export resultspython
ml.to_json('model.pas') # 保存模型
ml_loaded = ps.io.load('model.pas') # 加载模型
sim = ml.simulate()
sim.to_csv('simulation.csv') # 导出结果Model Statistics
模型统计指标
| Statistic | Description | Good Value |
|---|---|---|
| EVP | Explained variance percentage | >70% |
| RMSE | Root mean square error | Low (context-dependent) |
| AIC | Akaike Information Criterion | Lower = better |
| BIC | Bayesian Information Criterion | Lower = better |
| 统计指标 | 描述 | 理想值 |
|---|---|---|
| EVP | 解释方差百分比 | >70% |
| RMSE | 均方根误差 | 越低越好(取决于具体场景) |
| AIC | 赤池信息准则 | 数值越小越好 |
| BIC | 贝叶斯信息准则 | 数值越小越好 |
Common Patterns
常见模式
Compare Response Functions
比较响应函数
python
for rfunc in [ps.Gamma(), ps.Exponential(), ps.Hantush()]:
ml = ps.Model(head)
ml.add_stressmodel(ps.RechargeModel(precip, evap, rfunc=rfunc, name='r'))
ml.solve(report=False)
print(f"{rfunc.name}: EVP={ml.stats.evp():.1f}%, AIC={ml.stats.aic():.1f}")python
for rfunc in [ps.Gamma(), ps.Exponential(), ps.Hantush()]:
ml = ps.Model(head)
ml.add_stressmodel(ps.RechargeModel(precip, evap, rfunc=rfunc, name='r'))
ml.solve(report=False)
print(f"{rfunc.name}: EVP={ml.stats.evp():.1f}%, AIC={ml.stats.aic():.1f}")Forecast Future Levels
预测未来水位
python
ml.solve()
forecast = ml.simulate(tmin='2024-01-01', tmax='2025-12-31')
ml.plot(tmax='2025-12-31')python
ml.solve()
forecast = ml.simulate(tmin='2024-01-01', tmax='2025-12-31')
ml.plot(tmax='2025-12-31')River or Custom Stress
河流或自定义应力
python
river = pd.read_csv('river_stage.csv', index_col=0, parse_dates=True).squeeze()
sm = ps.StressModel(river, rfunc=ps.Exponential(), name='river',
settings='waterlevel')
ml.add_stressmodel(sm)python
river = pd.read_csv('river_stage.csv', index_col=0, parse_dates=True).squeeze()
sm = ps.StressModel(river, rfunc=ps.Exponential(), name='river',
settings='waterlevel')
ml.add_stressmodel(sm)When to Use vs Alternatives
适用场景与替代工具对比
| Use Case | Tool | Why |
|---|---|---|
| Groundwater time series analysis | Pastas | Purpose-built transfer function models |
| Well response to recharge/pumping | Pastas | Built-in stress models and response functions |
| Numerical groundwater flow (MODFLOW) | FloPy | Full 3D finite-difference groundwater model |
| Simple exponential decay fitting | Custom scipy | |
| Regional groundwater flow modelling | FloPy | Spatially distributed parameters and boundaries |
| Aquifer test analysis (pumping tests) | Aqtesolv / custom | Dedicated well test interpretation |
| Multi-well network analysis | Pastas | Model each well independently, compare responses |
| Signal decomposition | Pastas | Separate recharge, pumping, and trend contributions |
Choose Pastas when: You have groundwater level time series and want to model
responses to precipitation, evaporation, or pumping using transfer function noise
models. Excellent for rapid model building with diagnostics.
Choose FloPy when: You need spatially distributed groundwater flow modelling
with MODFLOW, including multiple layers, boundary conditions, and transport.
Choose custom scipy when: You only need to fit a simple analytical model
(e.g., Theis equation) to pumping test data without time series decomposition.
| 场景 | 工具 | 原因 |
|---|---|---|
| 地下水时间序列分析 | Pastas | 专为传递函数模型设计 |
| 水井对补给/抽水的响应 | Pastas | 内置应力模型与响应函数 |
| 数值地下水流动(MODFLOW) | FloPy | 完整的3D有限差分地下水模型 |
| 简单指数衰减拟合 | 自定义scipy实现 | |
| 区域地下水流动建模 | FloPy | 支持空间分布参数与边界条件 |
| 含水层试验分析(抽水试验) | Aqtesolv / 自定义实现 | 专为水井试验解译设计 |
| 多水井网络分析 | Pastas | 可独立建模每口水井,对比响应 |
| 信号分解 | Pastas | 可分离补给、抽水与趋势分量 |
选择Pastas的场景:当你拥有地下水位时间序列,需要使用传递函数噪声模型模拟其对降水、蒸发或抽水的响应时。Pastas在快速建模与诊断方面表现出色。
选择FloPy的场景:当你需要基于MODFLOW进行空间分布的地下水流动建模,包括多层结构、边界条件与运移模拟时。
选择自定义scipy实现的场景:当你仅需为抽水试验数据拟合简单解析模型(如泰斯方程),无需时间序列分解时。
Common Workflows
常见工作流
Groundwater Response Model with Diagnostics
带诊断的地下水响应模型
- Load head time series and stress data (precipitation, evaporation, pumping)
- Inspect data: check for gaps, outliers, and time coverage
- Create with observation data
ps.Model(head) - Add recharge stress with
ps.RechargeModel(precip, evap, rfunc=ps.Gamma()) - Add pumping or river stresses if applicable
- Solve model with
ml.solve() - Check EVP (>70%), RMSE, and AIC
- Run to inspect residuals
ml.plots.diagnostics() - Check residual autocorrelation; enable noise model if needed:
ml.solve(noise=True) - Compare response functions (Gamma vs Exponential vs Hantush) using AIC
- Extract step/block responses to interpret aquifer behavior
- Decompose signal into individual stress contributions
- Export model to JSON and simulation results to CSV
- 加载水头时间序列与应力数据(降水、蒸发、抽水)
- 检查数据:排查缺失值、异常值与时间覆盖范围
- 使用观测数据创建
ps.Model(head) - 通过添加补给应力
ps.RechargeModel(precip, evap, rfunc=ps.Gamma()) - 如有需要,添加抽水或河流应力
- 使用求解模型
ml.solve() - 检查EVP(>70%)、RMSE与AIC指标
- 运行检查残差
ml.plots.diagnostics() - 检查残差自相关性;如有需要启用噪声模型:
ml.solve(noise=True) - 使用AIC对比响应函数(Gamma vs Exponential vs Hantush)
- 提取阶跃/块响应以解读含水层行为
- 将信号分解为各应力的单独贡献
- 将模型导出为JSON,模拟结果导出为CSV
Tips
小贴士
- Start simple - Add stresses incrementally
- Check residuals - Should be white noise (use )
ml.plots.diagnostics() - Compare response functions - Use AIC/BIC to select best model
- Use daily data - Pastas works best with daily time series
- Normalize units - Precipitation in mm/day, head in meters
- 从简开始 - 逐步添加应力项
- 检查残差 - 残差应呈白噪声(使用)
ml.plots.diagnostics() - 对比响应函数 - 使用AIC/BIC选择最优模型
- 使用日度数据 - Pastas对日度时间序列的支持最佳
- 统一单位 - 降水单位为毫米/天,水头单位为米
Common Issues
常见问题
| Issue | Solution |
|---|---|
| Poor fit (low EVP) | Try different response functions |
| Residual autocorrelation | Add noise model: |
| Unstable parameters | Set parameter bounds or fix values |
| Missing stress data | Interpolate or use |
| 问题 | 解决方案 |
|---|---|
| 拟合效果差(EVP低) | 尝试不同的响应函数 |
| 残差存在自相关性 | 添加噪声模型: |
| 参数不稳定 | 设置参数边界或固定参数值 |
| 应力数据缺失 | 建模前先插值或使用 |
References
参考文献
- Stress Models - Available stress model types
- Response Functions - Response function selection
- Stress Models - 可用的应力模型类型
- Response Functions - 响应函数选择指南
Scripts
脚本
- scripts/groundwater_model.py - Complete groundwater modeling workflow
- scripts/groundwater_model.py - 完整的地下水建模工作流