Я думаю, причина в том, что вы ожидаете, что маскированные элементы массива mx
будут пропущены во время вычисления градиента, так что вместо вычисления градиента на x = np.array([100, 2, 3, 5, 5, 5, 10, 100])
мы вычислим его на x = np.array([2, 3, 5, 5, 5, 10])
, но реальное поведение отличается тем, что np.ma.MaskedArray
наследуется от np.ndarray
, а np.gradient()
не делает ничего особенного с np.ndarray
или его подклассами. Так, в случае mx = ma.masked_array(x, mask=[1, 0, 0, 0, 0, 0, 0, 1])
, градиент будет вычислен на массиве:
[--, 2, 3, 5, 5, 5, 10, --]
Сначала он попытается вычислить градиент для первого элемента с разницей первого порядка по умолчанию, а шаг h=1
(по умолчанию np.gradient
рассматривает шаги как одинарные в каждом измерении входных данных.):
gradient[0] = (mx[1] - mx[0]) / h
Поскольку это зависит от mx[0]
, который нельзя использовать с помощью mask
, значение gradient[0]
будет маскироваться как «True».
Когда он попытается вычислить градиент по индексу 1 для элемента, который вы воспринимаете как новую левую границу массива; этот элемент на самом деле не является граничным элементом ndarray
.
Когда он вычисляет градиент для элемента, который, по вашему мнению, является новой левой границей, он фактически использует формулу центральных разностей с однородными шагами h
, gradient[1] = (mx[2] - mx[0]) / 2h
, но поскольку mx[0]
маскируется как элемент, который не может быть использован, значение для gradient[1]
также не может быть получено, поэтому оно маскируется с помощью True
. То же самое происходит на другом конце массива.
Теперь, что касается маскировки чего-то посередине, предположим:
x = np.array([1, 2, 3, 4, 5])
mask = [0, 0, 1, 0, 0]
mx = ma.masked_array(x, mask=mask)
Функция градиента, примененная к mx снова, будет использовать формулу центральной разности для однородных шагов, и когда мы вычисляем:
masked_gradient[1] = (mx[2] - mx[0]) / 2h
masked_gradient[3] = (mx[4] - mx[2]) / 2h
Ни одно из этих значений не может быть вычислено, поскольку mx [2] маскируется с помощью True
. И в то же время:
masked_gradient[2] = (mx[3] - mx[1]) / 2h
Может быть оценено, потому что все значения, от которых он зависит, маскируются как False
, поэтому результат будет иметь маску:
[0, 1, 0, 1, 0]
А значения:
[1.0, --, 1.0, --, 1.0]