python - numpy masked array fill value still being accessed -
i trying process image masked array handle nodata areas. decided little testing first on 1 dimensional arrays, , seeing odd. here test code:
= np.array([0,1,4,3,4,-9999,33,34,-9999]) = np.ma.maskedarray(a) am.mask = (am==-9999) z = np.arange(35) z[am] i expect indexing z array masked array succeed seeing following error:
runtime error traceback (most recent call last): file "<string>", line 1, in <module> indexerror: index -9999 out of bounds size 35 can comment on how correctly coded? can run following command success:
z[a[a>0]] which same thing.
thanks!
it's bad idea use marked arrays purposes of indexing, precisely because behavior should happen @ masked value undefined.
think way: when @ array a , array z, can "ok, a[0] = 0 z[a[0]] makes sense." , on until come across a[5] = -9999 when can say, "ok, can't make sense index z" , exception can raised.
this in fact happen when naively use am index set ... reverts using am.data contains all of original values. if instead tried use [z[i] in am] run smack problem of encountering numpy.ma.core.maskedconstant not sensible value indexing -- not fetching value nor ignoring request fetch value.
in [39]: l = [x x in am] in [40]: l out[40]: [0, 1, 4, 3, 4, masked, 33, 34, masked] in [41]: type(l[-1]) out[41]: numpy.ma.core.maskedconstant (in fact, if try index on 1 of these guys, indexerror: arrays used indices must of integer (or boolean) type).
but happens if come across masked value in am.filled()? entry @ 5th index of am.filled() won't instance of numpy.ma.core.maskedconstant -- whatever fill value has been selected you. if fill value makes sense index, fetch value indexing @ index. take 0 example. seems innocuous, neutral fill value, represents valid index, 2 accesses 0th entry of z:
in [42]: am.fill_value = 0 in [43]: z[am.filled()] out[43]: array([ 0, 1, 4, 3, 4, 0, 33, 34, 0]) and isn't mask supposed either!
a half-baked approach iterate on am , exclude type of np.ma.core.maskedconstant:
in [45]: z[np.array([x x in if type(x) not np.ma.core.maskedconstant])] out[45]: array([ 0, 1, 4, 3, 4, 33, 34]) but clearer expression of of use plain logical indexing in first place:
in [47]: z[a[a != -9999]] out[47]: array([ 0, 1, 4, 3, 4, 33, 34]) note logical indexing work fine 2d arrays, long you're willing accept once higher dimensional array indexed logically, if result no longer conformable same regular 2d shape, presented in 1d, this:
in [58]: a2 = np.array([[10, -9999, 13], [-9999, 1, 8], [1, 8, 1]]) in [59]: a2 out[59]: array([[ 10, -9999, 13], [-9999, 1, 8], [ 1, 8, 1]]) in [60]: z2 = np.random.rand(3,3) in [61]: z2[np.where(a2 != -9999)] out[61]: array([ 0.4739082 , 0.13629442, 0.46547732, 0.87674102, 0.08753297, 0.57109764, 0.39722408]) if instead want similar effect of mask, can set values equal nan (for float arrays):
in [66]: a2 = np.array([[10, -9999, 13], [-9999, 1, 8], [1, 8, 1]], dtype=np.float) in [67]: a2 out[67]: array([[ 1.00000000e+01, -9.99900000e+03, 1.30000000e+01], [ -9.99900000e+03, 1.00000000e+00, 8.00000000e+00], [ 1.00000000e+00, 8.00000000e+00, 1.00000000e+00]]) in [68]: a2[np.where(a2 == -9999)] = np.nan in [69]: a2 out[69]: array([[ 10., nan, 13.], [ nan, 1., 8.], [ 1., 8., 1.]]) this form of masking nan suitable lot of vectorized array computations in numpy, although can pain worry converting integer-based image data floating point first, , converting safely @ end.
Comments
Post a Comment