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
相关产品推荐
相关产品推荐

