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
|
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:
|
def preprocess_spectra(self, spectra: pd.DataFrame) -> np.ndarray:
|
||||||
"""
|
"""
|
||||||
对光谱数据进行预处理 + 跨传感器光谱重采样。
|
对光谱数据进行预处理 + 跨传感器光谱重采样。
|
||||||
@ -477,34 +518,10 @@ class WaterQualityInference:
|
|||||||
metadata = self.loaded_model_data.get('metadata', {})
|
metadata = self.loaded_model_data.get('metadata', {})
|
||||||
|
|
||||||
# ═══════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════
|
||||||
# ★ DualStream_MNF:纯光谱 → 重采样到训练波长 → pipeline.predict()
|
# ★ DualStream_MNF:纯光谱重采样 → pipeline.predict() 全自动
|
||||||
# Pipeline 内置的 FeatureUnion[PhysicalExtractor + MNF]
|
|
||||||
# 自动计算物理指数和降维,无需外部补 WQI
|
|
||||||
# ═══════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════
|
||||||
if actual_preprocess_method == "DualStream_MNF" and isinstance(model, Pipeline):
|
if actual_preprocess_method == "DualStream_MNF" and isinstance(model, Pipeline):
|
||||||
print("[DualStream_MNF] 推理:纯光谱重采样 → Pipeline 全自动处理")
|
return self._preprocess_dual_stream(spectra, metadata)
|
||||||
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
|
|
||||||
|
|
||||||
train_wavelengths = metadata.get('train_wavelengths', None)
|
train_wavelengths = metadata.get('train_wavelengths', None)
|
||||||
# 旧模型无 train_wavelengths → 不做波长匹配,走下方分支 B 的 linspace 路径
|
# 旧模型无 train_wavelengths → 不做波长匹配,走下方分支 B 的 linspace 路径
|
||||||
|
|||||||
Reference in New Issue
Block a user