0

Motivation: in a list of numeric values I try to find the index of the smallest value - with the side condition, that the value has to below a certain treshold. Here is an example where everything works as expected

import numpy as np
a = np.array([1, 5, -4])
threshold = 3
b = np.ma.MaskedArray(a, a >= threshold)
np.ma.argmin(b)  # returns 2, since a[2] is -4 which is the smallest element < 3

Here is a case where np.ma.argmin does something unexpected:

a = np.array([4, 5])
threshold = 3
b = np.ma.MaskedArray(a, a >= threshold)
np.ma.argmin(b)  # returns 0, expected a None etc. since there is no element < 3

Why is this and how can I make it return None? Note: setting fill_value = None did not help.

Qaswed
  • 3,649
  • 7
  • 27
  • 47

1 Answers1

0

The code for argmin is:

def argmin(self, axis=None, fill_value=None, out=None):
    if fill_value is None:
        fill_value = minimum_fill_value(self)
    d = self.filled(fill_value).view(ndarray)
    return d.argmin(axis, out=out)

It fills it with the appropriate fill value (for int dtype that's the largest integer), and then does a regular array argmin. If all values are masked, then all are this max, and the first one is the argmin.

b.min() returns a special ma value ma.MaskedConstant. So you may have to wrap your argmin call with some sort of test for this value. I don't off hand see a np.ma.is... function that would test this. But there may be something in the docs.

hpaulj
  • 221,503
  • 14
  • 230
  • 353
  • 1. What ist `minimum_fill_value`? 2. Is there a rational behind not filling `None`? 3. Do you have a better workaround than `None if all(b.mask) else np.ma.argmin(b)`? – Qaswed Mar 20 '20 at 07:34
  • You can't put `None` in a int (or float) dtype array. – hpaulj Mar 20 '20 at 07:47