fix: Kriging 整体拟合+变异函数容错+自适应分层抽样+高斯平滑+掩膜修复

This commit is contained in:
duxin
2026-07-27 18:08:37 +08:00
parent c8ab4e029e
commit de9d6f0835

View File

@ -672,7 +672,52 @@ class ContentMapper:
grid_y = grid_yy[:, 0] grid_y = grid_yy[:, 0]
total_cells = len(grid_x) * len(grid_y) total_cells = len(grid_x) * len(grid_y)
# ── 1) 全局变异函数拟合(多模型容错回退)── # ── 1) 全局变异函数拟合(自适应分层抽样防 OOM)──
# 变异函数拟合内存 ≈ N²×8 bytes。预留 1.5GB 安全上限 → N_max≈14000
_vario_pts = points
_vario_vals = values
# 从系统内存动态估算可容纳的最大点数
try:
import psutil
_avail_gb = psutil.virtual_memory().available / (1024**3)
except Exception:
_avail_gb = 4.0 # 保守兜底
# 计算安全点数:留 50% 余量给 Python 开销
_MAX_VARIOGRAM_PTS = int(np.sqrt(max(_avail_gb * 0.5, 0.5) * 1024**3 / 8))
_MAX_VARIOGRAM_PTS = np.clip(_MAX_VARIOGRAM_PTS, 3000, 20000)
if len(points) > _MAX_VARIOGRAM_PTS:
# 空间分层抽样网格覆盖全水域每格保留1点
_grid = int(np.ceil(np.sqrt(_MAX_VARIOGRAM_PTS)))
_x_bins = np.linspace(points[:, 0].min(), points[:, 0].max(), _grid + 1)
_y_bins = np.linspace(points[:, 1].min(), points[:, 1].max(), _grid + 1)
_keep = np.zeros(len(points), dtype=bool)
for _ix in range(_grid):
for _iy in range(_grid):
_cell = (
(points[:, 0] >= _x_bins[_ix]) &
(points[:, 0] < _x_bins[_ix + 1]) &
(points[:, 1] >= _y_bins[_iy]) &
(points[:, 1] < _y_bins[_iy + 1])
)
if _cell.any():
_keep[np.where(_cell)[0][0]] = True
_kept_idx = np.where(_keep)[0]
if len(_kept_idx) < _MAX_VARIOGRAM_PTS:
_remaining = np.where(~_keep)[0]
_extra = np.random.default_rng(42).choice(
_remaining,
min(_MAX_VARIOGRAM_PTS - len(_kept_idx), len(_remaining)),
replace=False,
)
_kept_idx = np.concatenate([_kept_idx, _extra])
_vario_pts = points[_kept_idx]
_vario_vals = values[_kept_idx]
print(f" [Kriging] 采样点 {len(points)} > {_MAX_VARIOGRAM_PTS}"
f"(可用内存 {_avail_gb:.1f}GB)"
f"空间分层抽样 → {len(_kept_idx)}"
f"(网格 {_grid}×{_grid},全覆盖)")
_vario_models = [ _vario_models = [
('spherical', {'nugget': 1e-6}), ('spherical', {'nugget': 1e-6}),
('exponential', {'nugget': 1e-6}), ('exponential', {'nugget': 1e-6}),
@ -684,7 +729,7 @@ class ContentMapper:
for _vm_name, _vm_kw in _vario_models: for _vm_name, _vm_kw in _vario_models:
try: try:
ok_model = OrdinaryKriging( ok_model = OrdinaryKriging(
points[:, 0], points[:, 1], values, _vario_pts[:, 0], _vario_pts[:, 1], _vario_vals,
variogram_model=_vm_name, variogram_model=_vm_name,
verbose=False, enable_plotting=False, verbose=False, enable_plotting=False,
**_vm_kw, **_vm_kw,