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