НП.где и замаскированный массив
Я работаю с маскированными массивами благодаря некоторой помощи, которую я получил на stackoverflow, но я сталкиваюсь с проблемой с np.где оценка маскируемого массива.
Мой маскированный массив:
m_pt0 = np.ma.masked_array([1, 2, 3, 0, 4, 7, 6, 5],
mask=[False, True, False, False,
False, False, False, False])
И печатает вот так:
In [24]: print(m_pt0)
[1 -- 3 0 4 7 6 5]
И я ищу индекс в m_pt0, где m_pt0 = 0, я ожидал бы, что
np.where(0 == m_pt0)
Вернет:
(array([3]))
Однако, несмотря на маску (или из-за нее?), Я вместо этого получаю
(array([1, 3]),)
Весь смысл использования маска предназначена для того, чтобы избежать доступа к индексам, которые являются "пустыми", поэтому как я могу использовать where (или другую функцию) только для извлечения индексов, которые не маскируются и соответствуют моим булевым критериям.
2 ответа:
Необходимо использовать маскированный вариант функции
where()
, иначе она вернет неправильные или нежелательные результаты для маскированных массивов. То же самое относится и к другим функциям, таким какpolyfit()
.То есть:
In [2]: np.ma.where(0 == m_pt0) Out[2]: (array([3]),)
Тест на равенство может создать путаницу. В результате получается еще один маскированный массив:
In [19]: 0 == m_pt0 Out[19]: masked_array(data = [False -- False True False False False False], mask = [False True False False False False False False], fill_value = True)
Маскируемый массив имеет атрибуты
.data
и.mask
.numpy
функции, которые не осознают MA, просто видят.data
:In [20]: _.data Out[20]: array([False, True, False, True, False, False, False, False], dtype=bool)
np.where
видит 2True
и возвращаетIn [23]: np.where(0 == m_pt0) Out[23]: (array([1, 3], dtype=int32),) In [24]: np.where((0 == m_pt0).data) Out[24]: (array([1, 3], dtype=int32),)
По возможности лучше использовать версию функции
np.ma
:In [25]: np.ma.where(0 == m_pt0) Out[25]: (array([3], dtype=int32),)
Глядя на код для
np.source(np.ma.where)
я вижу, что он делаетif missing == 2: return filled(condition, 0).nonzero() (plus lots of code for the 3 argument use)
Что
filled
делает:In [27]: np.ma.filled((0 == m_pt0),0) Out[27]: array([False, False, False, True, False, False, False, False], dtype=bool)
MA
функции часто заменяйте замаскированные значения чем-то безобидным (0 в данном случае) или используйтеcompressed
, чтобы удалить их из рассмотрения.In [36]: m_pt0.compressed() Out[36]: array([1, 3, 0, 4, 7, 6, 5]) In [37]: m_pt0.filled(100) Out[37]: array([ 1, 100, 3, 0, 4, 7, 6, 5])
Функция numpy будет корректно работать на MA, если она делегирует работу собственному методу массива.
In [41]: np.nonzero(m_pt0) Out[41]: (array([0, 2, 4, 5, 6, 7], dtype=int32),) In [42]: m_pt0.nonzero() Out[42]: (array([0, 2, 4, 5, 6, 7], dtype=int32),) In [43]: np.where(m_pt0) Out[43]: (array([0, 1, 2, 4, 5, 6, 7], dtype=int32),)
np.nonzero
делегаты.np.where
нет.
repr
маскируемого массива показывает маску. Егоstr
просто показывает замаскированные данные:In [31]: m_pt0 Out[31]: masked_array(data = [1 -- 3 0 4 7 6 5], mask = [False True False False False False False False], fill_value = 999999) In [32]: str(m_pt0) Out[32]: '[1 -- 3 0 4 7 6 5]'