refactor: 抽取 _preprocess_dual_stream 独立方法
- preprocess_spectra 中 DualStream_MNF 分支从 25 行内联代码 变为 1 行方法调用: self._preprocess_dual_stream(spectra, metadata) - 新方法含完整文档、fallback 路径、重采样逻辑 - 与旧 WQI 补齐/linspace 路径完全解耦
This commit is contained in:
@ -433,6 +433,47 @@ class WaterQualityInference:
|
||||
|
||||
return None
|
||||
|
||||
# ═══════════════════════════════════════════════════════════
|
||||
# DualStream_MNF 专用预处理:纯光谱重采样 → Pipeline 全自动
|
||||
# ═══════════════════════════════════════════════════════════
|
||||
|
||||
def _preprocess_dual_stream(self, spectra: pd.DataFrame,
|
||||
metadata: dict) -> np.ndarray:
|
||||
"""纯光谱重采样到训练波长网格,返回后由 pipeline.predict() 全自动处理。
|
||||
|
||||
Pipeline 内置 FeatureUnion[PhysicalExtractor + MNFTransformer],
|
||||
会自动完成物理指数计算和 MNF 降维,无需外部补 WQI。
|
||||
"""
|
||||
train_wl = metadata.get('train_wavelengths', None)
|
||||
if train_wl is None or len(train_wl) == 0:
|
||||
print("[DualStream_MNF] ⚠ 模型无 train_wavelengths,fallback 原样输入")
|
||||
return spectra.values
|
||||
|
||||
# 提取纯光谱列
|
||||
spec_cols = []
|
||||
for c in spectra.columns:
|
||||
try:
|
||||
float(str(c)); spec_cols.append(c)
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
|
||||
# np.interp 重采样:308/113/任意波段 → 模型训练波长
|
||||
spec_data = spectra[spec_cols].values.astype(np.float64)
|
||||
src_wl = np.array([float(c) for c in spec_cols], dtype=np.float64)
|
||||
dst_wl = np.array(train_wl, dtype=np.float64)
|
||||
resampled = np.zeros((spec_data.shape[0], len(dst_wl)), dtype=np.float64)
|
||||
for i in range(spec_data.shape[0]):
|
||||
resampled[i] = np.interp(dst_wl, src_wl, spec_data[i],
|
||||
left=np.nan, right=np.nan)
|
||||
resampled = np.nan_to_num(resampled, nan=0.0)
|
||||
|
||||
result = pd.DataFrame(resampled,
|
||||
columns=[f'{wl:.6f}' for wl in train_wl])
|
||||
print(f"[DualStream_MNF] 纯光谱重采样: {len(spec_cols)} → {len(train_wl)} 列")
|
||||
print(f"[DualStream_MNF] pipeline.predict() 将自动完成 Physical+MNF 变换")
|
||||
print(f"[特征对齐] 最终输入维度: {result.shape}")
|
||||
return result.values
|
||||
|
||||
def preprocess_spectra(self, spectra: pd.DataFrame) -> np.ndarray:
|
||||
"""
|
||||
对光谱数据进行预处理 + 跨传感器光谱重采样。
|
||||
@ -477,34 +518,10 @@ class WaterQualityInference:
|
||||
metadata = self.loaded_model_data.get('metadata', {})
|
||||
|
||||
# ═══════════════════════════════════════════════════════════
|
||||
# ★ DualStream_MNF:纯光谱 → 重采样到训练波长 → pipeline.predict()
|
||||
# Pipeline 内置的 FeatureUnion[PhysicalExtractor + MNF]
|
||||
# 自动计算物理指数和降维,无需外部补 WQI
|
||||
# ★ DualStream_MNF:纯光谱重采样 → pipeline.predict() 全自动
|
||||
# ═══════════════════════════════════════════════════════════
|
||||
if actual_preprocess_method == "DualStream_MNF" and isinstance(model, Pipeline):
|
||||
print("[DualStream_MNF] 推理:纯光谱重采样 → Pipeline 全自动处理")
|
||||
train_wl = metadata.get('train_wavelengths', None)
|
||||
if train_wl is not None and len(train_wl) > 0:
|
||||
spec_cols = []
|
||||
for c in spectra.columns:
|
||||
try:
|
||||
float(str(c)); spec_cols.append(c)
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
spec_data = spectra[spec_cols].values.astype(np.float64)
|
||||
src_wl = np.array([float(c) for c in spec_cols], dtype=np.float64)
|
||||
dst_wl = np.array(train_wl, dtype=np.float64)
|
||||
resampled = np.zeros((spec_data.shape[0], len(dst_wl)), dtype=np.float64)
|
||||
for i in range(spec_data.shape[0]):
|
||||
resampled[i] = np.interp(dst_wl, src_wl, spec_data[i],
|
||||
left=np.nan, right=np.nan)
|
||||
resampled = np.nan_to_num(resampled, nan=0.0)
|
||||
spectra = pd.DataFrame(resampled,
|
||||
columns=[f'{wl:.6f}' for wl in train_wl])
|
||||
print(f"[DualStream_MNF] 纯光谱重采样完成: {spectra.shape[1]} 列 "
|
||||
f"→ pipeline.predict() 将自动完成 Physical+MNF 变换")
|
||||
print(f"[特征对齐] 最终输入维度: {spectra.shape}")
|
||||
return spectra.values
|
||||
return self._preprocess_dual_stream(spectra, metadata)
|
||||
|
||||
train_wavelengths = metadata.get('train_wavelengths', None)
|
||||
# 旧模型无 train_wavelengths → 不做波长匹配,走下方分支 B 的 linspace 路径
|
||||
|
||||
Reference in New Issue
Block a user