1

Is there a cleaner way to initialize a numpy masked array from a non-ma, with all masked values False, than this?

masked_array = np.ma.masked_array(array, mask=np.zeros_like(array, dtype='bool'))

The duplicate reference to array seems unnecessary and clunky. If you do not give the mask= parameter, the mask defaults to a scalar boolean, which prevents sliced access to the mask.

1
  • Any alternative would do the samething under the covers Commented Mar 26, 2020 at 13:53

1 Answer 1

2

You should be able to just set the mask to False:

>>> array = np.array([1,2,3])
>>> masked_array = np.ma.masked_array(array, mask=False)
>>> masked_array
masked_array(data = [1 2 3],
             mask = [False False False],
       fill_value = 999999)

I saw hpaulj’s comment and played around with different ways of solving this issue and comparing performance. I can’t explain the difference, but @hpaulj seems to have a much deeper understanding of how numpy works. Any input on why m3() executes so much faster would be most appreciated.

def origM():
    array = np.array([1,2,3])
    return np.ma.masked_array(array, mask=np.zeros_like(array, dtype='bool'))

def m():
    array = np.array([1,2,3])
    return np.ma.masked_array(array, mask=False)    

def m2():
    array = np.array([1,2,3])
    m = np.ma.masked_array(array)
    m.mask = False
    return m

def m3():
    array = np.array([1,2,3])
    m = array.view(np.ma.masked_array)
    m.mask = False
    return m

>>> origM()
masked_array(data = [1 2 3],
             mask = [False False False],
       fill_value = 999999)

All four return the same result:

>>> m()
masked_array(data = [1 2 3],
             mask = [False False False],
       fill_value = 999999)

>>> m2()
masked_array(data = [1 2 3],
             mask = [False False False],
       fill_value = 999999)

>>> m3()
masked_array(data = [1 2 3],
             mask = [False False False],
       fill_value = 999999)

m3() executes the fastest:

>>> timeit.timeit(origM, number=1000)
0.024451958015561104
>>> timeit.timeit(m, number=1000)
0.0393978749634698
>>> timeit.timeit(m2, number=1000)
0.024049583997111768
>>> timeit.timeit(m3, number=1000)
0.018082750029861927
Sign up to request clarification or add additional context in comments.

1 Comment

Huh, neat - I didn't pick that up from the docs, but this answer is implicitly hinted at there.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.