You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

np.ma.median处理含NaN矩阵为何仅特定尺寸触发MaskError?

问题:numpy.ma.median仅在特定矩阵尺寸下触发MaskError

我正在开发一款能处理NaN矩阵且避免崩溃的代码,使用numpy 1.23.5版本。核心逻辑如下:

  • 创建全NaN网格
  • 生成环形掩码并应用到网格
  • 计算环内元素的中位数

当out_radius设为31时,代码正常执行,最终返回NaN;但将out_radius改为28及更小值时,执行np.ma.median会触发MaskError('Cannot alter the masked element.')。

复现正常运行的代码

from math import floor
from scipy.signal import convolve
import numpy as np

in_radius = 10
out_radius = 31
box_size = 5

box=np.ones((box_size,box_size))
padding=floor(box_size/2)

y,x=np.ogrid[-1*out_radius:out_radius+1,-1*out_radius:out_radius+1]
grid_mask=np.logical_or(x**2+y**2<in_radius**2,x**2+y**2>out_radius**2)

grid = np.empty((67,67),)
grid[:] = np.nan

smoothed=convolve(grid,box,method='direct',mode='valid') / 2

noisepix=np.ma.masked_array(smoothed,grid_mask)
median_signal = np.ma.median(noisepix)

复现报错的代码

in_radius = 10
out_radius = 28
box_size = 5

box=np.ones((box_size,box_size))
padding=floor(box_size/2)

y,x=np.ogrid[-1*out_radius:out_radius+1,-1*out_radius:out_radius+1]
grid_mask=np.logical_or(x**2+y**2<in_radius**2,x**2+y**2>out_radius**2)

grid = np.empty((61,61),)
grid[:] = np.nan

smoothed=convolve(grid,box,method='direct',mode='valid') / 2

noisepix=np.ma.masked_array(smoothed,grid_mask)
median_signal = np.ma.median(noisepix)

完整报错信息

MaskError                                 Traceback (most recent call last)
/var/folders/89/zgv9nv5563n89pzs55bv6mzm0000gq/T/ipykernel_17229/2791888929.py in <module>
     21 
     22 noisepix=np.ma.masked_array(smoothed,grid_mask)
---> 23 median_signal = np.ma.median(noisepix)

~/opt/anaconda3/lib/python3.9/site-packages/numpy/ma/extras.py in median(a, axis, out, overwrite_input, keepdims)
    733             return m
    734 
---> 735     r, k = _ureduce(a, func=_median, axis=axis, out=out,
    736                     overwrite_input=overwrite_input)
    737     if keepdims:

~/opt/anaconda3/lib/python3.9/site-packages/numpy/lib/function_base.py in _ureduce(a, func, **kwargs)
   3723         keepdim = (1,) * a.ndim
   3724 
---> 3725     r = func(a, **kwargs)
   3726     return r, keepdim
   3727 

~/opt/anaconda3/lib/python3.9/site-packages/numpy/ma/extras.py in _median(a, axis, out, overwrite_input)
    779             if not odd:
    780                 s = np.true_divide(s, 2., casting='safe', out=out)
---> 781             s = np.lib.utils._median_nancheck(asorted, s, axis)
    782         else:
    783             s = mid.mean(out=out)

~/opt/anaconda3/lib/python3.9/site-packages/numpy/lib/utils.py in _median_nancheck(data, result, axis)
   1052             return data.dtype.type(np.nan)
   1053 
---> 1054         result[n] = np.nan
   1055     return result
   1056 

~/opt/anaconda3/lib/python3.9/site-packages/numpy/ma/core.py in __setitem__(self, indx, value)
   3344         """
   3345         if self is masked:
---> 3346             raise MaskError('Cannot alter the masked element.')
   3347         _data = self._data
   3348         _mask = self._mask

MaskError: Cannot alter the masked element.

我已经知道可以通过将NaN替换为其他值的方式规避该问题,但想搞清楚为什么这个报错只会在特定尺寸的矩阵下出现。

内容的提问来源于stack exchange,提问作者loberhel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 19:53:14