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

Popular posts from this blog

javascript - AngularJS custom datepicker directive -

javascript - jQuery date picker - Disable dates after the selection from the first date picker -