SciPy median_filter 的单元素 mirror 输出异常值
一维单元素数据用 mirror 中值滤波后出现极小浮点数,可能来自 rank-filter 快速路径。用二维单行保持滤波轴和边界语义,复核输出。
median_filter(np.array([0.5]), size=3, mode="mirror") 应保留这个唯一值,却返回约 1.6e-322 的极小数,甚至不同进程得到不同结果。遇到这种表现,应先停用这批滤波输出,检查维数、窗口和边界模式,不要把异常值当成正常的平滑效果。
SciPy 1.15 系列之后的一维 rank-filter 快速路径有相关故障记录,1.18.1 仍可涉及;median_filter、rank_filter 和 percentile_filter 共用其中部分实现。最清楚的触发样本是一维单元素、size=3、mode="mirror"。不能简化成“所有大于输入的窗口都错”:同一输入的某些更大窗口反而可能正常。
先确认异常在一维快速路径
记录输入 shape、dtype、窗口大小、origin、mode 和是否提供了输出数组。正式 1.18.1 对特定一维输入调用专门实现,多维输入采用另一条 rank-filter 路径。因此同样的值装进二维单行,可能避开这个问题。
只比较输出是否有限不够。对 [0.5],一个很小但有限的数依然是错误结果;对普通数据,也应比较该边界模式所定义的窗口样本。
保留 mirror 语义,绕过一维分支
对于本来就是一维数组、沿唯一数据轴做中值滤波的应用,可以临时把它提升为单行,窗口只沿数据轴展开:
import numpy as np
from scipy.ndimage import median_filter
x = np.array([0.5], dtype=np.float64)
window = 3
filtered = median_filter(
x[np.newaxis, :],
size=(1, window),
mode="mirror",
)[0]
这里新增轴的窗口为 1,原数据轴窗口仍为 3,最后取回一维结果。这个片段没有承接自定义 footprint、非零 origin、显式 output 或多轴滤波;项目使用这些参数时,需要按轴对应关系单独核对,不能直接丢弃它们。
二维路径仍要计算并分配结果,需在原有资源预算内使用。对大型输入、复杂 footprint 或特殊 dtype,不应仅凭单元素样本正确就全量切换。
将 mirror 换成 reflect、nearest 或 constant,会改变边界外样本如何延伸。这可能使报错消失,却不一定符合原信号处理含义;先明确允许的边界政策,不能把换模式称为等价修复。
用可推导的小样本核对边缘
单元素样本的全部输出应仍为 0.5。再加入短数组,覆盖输入两端、不同窗口和生产 dtype,按 mirror 定义核对结果,并比较一维与二维路径。窗口改变后偶然正常,不能证明已找到了可靠的窗口上限。
若使用 rank 或 percentile 接口,还要保留对应的秩或百分位数,避免把中值示例机械推广。已有异常输出进入后续计算时,保留原输入并确定受影响批次,再重算;只把结果中的微小数替换为零会改变本来可能非零的数据。
后续正式版本若调整快速实现,先复查同一组短输入和边界条件,再决定是否移除二维绕行。当前不能凭开发补丁或一次运行正常,承诺所有一维窗口组合都已修好。


