Создайте логическую маску для трехмерного массива - PullRequest
0 голосов
/ 22 июня 2019

У меня есть массив массивов 3D размером [2000x7200x40] (мы назовем его «осадка»), который я хотел бы замаскировать для определенных значений (-9999), которые будут исключены из классификации scipy.mstats.rankdata(precip,axis=2,use_missing=False).

Думайте о данных как:

[-9999, 2, 3, 5, -9999
       4, 7, -9999, 6]...

Мне в большинстве случаев это не удалось; кажется, что большинство np.ma функций, таких как np.ma.masked_invalid, применяются только к 1-D массиву.

-9999 значения могут быть разными для каждого массива во временном ряду (z).

Я пробовал такие простые функции, как:

 #mask the -9999 values out
   mask = np.empty_like(precip)
   mask = ~(precip == -9999).all(axis=2,keepdims=True)

, а затем транслировать это в трехмерный массив с mask = [numpy.newaxis,:,:]

Однако это приводит к массиву 2000x7200x1, который затем выдает ошибку измерения при умножении на осадку, поскольку он ожидает массив измерения 40.

Есть ли какая-то простая функция или фрагмент кода, который я пропустил, который легко сделает это для меня? Спасибо за любую помощь!

Ответы [ 2 ]

0 голосов
/ 27 июня 2019

Итак, я полностью отказался от метода ранжирования mstats;он балансирует, когда вся строка замаскирована.

В итоге я использовал приведенный выше код маскирования: mask = ~(precip == -9999).all(axis=2, keepdims=True)

после apply_along_axis(lambda a: scipy.stats.ranking(a), axis=2, precip)) метода

Тогда просто ranks = ranks*mask сделал хитрость, чтобы замаскировать значения, которые всегда были -9999 в данных об осадках.

Надеюсь, это поможет кому-то запутаться в том, что mstats.ranking покажет ошибку 0-D-массива в будущем.Модуль scipy.stats.ranking также кажется НАМНОГО быстрее, чем модуль scipy.mstats.ranking в качестве дополнительного бонуса.

0 голосов
/ 22 июня 2019

Вы определенно можете использовать маскированные многомерные массивы.Однако вы должны убедиться, что ваша маска и данные имеют одинаковый размер.

>>> mask = ~(precip == -9999).all(axis=2, keepdims=True)
>>> mask.shape
(2000, 7200, 1)
>>> repeated_mask = np.repeat(mask, precip.shape[-1], axis=-1) # Ensure same shape
>>> repeated_mask.shape == precip.shape
True
>>> ma = np.ma.masked_array(precip, mask=repeated_mask)
>>> ma.shape == precip.shape
True

Обратите внимание, что вы также можете без проблем умножить маску на исходный массив данных, если вы не добавите дополнительная ось с np.newaxis.Аргумент keepdims=True для np.all означает, что число измерений одинаково, и поэтому mask можно напрямую умножить на precip благодаря механизмам Numpy, передающим .Например:

>>> mask = ~(precip == -9999).all(axis=2, keepdims=True)
>>> mask.shape
(2000, 7200, 1)
>>> (precip * mask).shape == precip.shape # `mask` will be broadcast to the shape of `precip`
True
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...