2016-04-12 10 views
2

Учитывая образец маскируется массив и запрос на KDTree,KDTree с замаскированными массивами

In [6]: data = np.arange(9).reshape((3,3))*1.0 

In [7]: madata = np.ma.array(data) 

In [9]: madata[1,1] = ma.masked 

In [10]: madata 
Out[10]: 
masked_array(data = 
[[0.0 1.0 2.0] 
[3.0 -- 5.0] 
[6.0 7.0 8.0]], 
     mask = 
[[False False False] 
[False True False] 
[False False False]], 
    fill_value = 1e+20) 

In [11]: from scipy.spatial import KDTree 

In [12]: matree = KDTree(madata) 

In [13]: matree.query([3,0,5]) 
Out[13]: (4.0, 1) 

Является ли это действительным для запроса дерева с использованием не-замаскированный массива? или маска-массив должен использоваться, поскольку дерево построено с использованием маскированных массивов.

Другой вопрос, является ли это разумным подходом найти наиболее похожие пары данных, что-то похожее на поиск наиболее похожих строк еще для числовых значений? Мой исходный набор данных составляет около 50 к на 20, который содержит много отсутствующих значений. Поэтому желательно использовать маскированные массивы и быструю реализацию.

Спасибо.

ответ

2

Не считайте, что KDTree делает что-то особенное с маскировкой. Я предполагаю, что он использует базовый массив данных как есть.

Маскированный массив имеет атрибут data и атрибут mask. Функции и методы np.ma обращают на них внимание. Но для многих задач они fill их данные с подходящим значением, а затем делают регулярные действия numpy. Например, если суммировать строки или столбцы, он заменит маскированные элементы на 0; если взять продукт, с 1s.

Изучите документацию KDTree. Если они говорят что-то об использовании маскированных массивов, следуйте этим инструкциям. Но если вы ничего не найдете, возможно, игнорирует маску.


Посмотрите на код KDTree. Это init начинается с:

def __init__(self, data, leafsize=10): 
    self.data = np.asarray(data) 
    .... 

Посмотрите на np.asarray(madata). Результатом является базовый data; а не маскированный массив. Поэтому маскирование массива не имеет значения.


Посмотрите, что происходит, когда есть Nan в данном:

установки
In [256]: tree.data 
Out[256]: 
array([[ 0., 1., 2.], 
     [ 3., nan, 5.], 
     [ 6., 7., 8.]]) 

In [257]: tree.query([3,4,5]) 
C:\Users\paul\AppData\Local\Enthought\Canopy\User\lib\site-packages\scipy\spatial\kdtree.py:314: RuntimeWarning: invalid value encountered in maximum 
    side_distances = np.maximum(0,np.maximum(x-self.maxes,self.mins-x)) 
Out[257]: (5.196152422706632, 0) 

по умолчанию отображать предупреждение, как этот первый раз он встречается в сеансе (или контексте).

In [265]: np.maximum([1,2,0,np.nan],[3,2,0,0]) 
-c:1: RuntimeWarning: invalid value encountered in maximum 
Out[265]: array([ 3., 2., 0., nan]) 

In [266]: np.maximum([1,2,0,np.nan],[3,2,0,0]) 
Out[266]: array([ 3., 2., 0., nan]) 

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

Можете ли вы опустить пункты NaN?

маскированной-массив сжатого не может быть то, что вы хотите, так как она возвращает сплюснутый версию массива:

In [268]: madata.compressed() 
Out[268]: array([ 0., 1., 2., 3., 5., 6., 7., 8.]) 

или заливать что-то полезное?

In [271]: madata.filled(999) 
Out[271]: 
array([[ 0., 1., 2.], 
     [ 3., 999., 5.], 
     [ 6., 7., 8.]]) 
+0

Спасибо за объяснение. Как насчет наличия NAN в данных? Может ли KDTree правильно обрабатывать эти ситуации? NAN - основная причина, по которой я намерен использовать маскированные массивы. –

+1

см. Мои правки с nans. – hpaulj

+0

Таким образом, нет проблемы с конструированием дерева, но запрос кажется бессмысленным, когда в данных есть NaN. Это главный вопрос. Если я заполню данные другими номерами, разве это не приведет к смещению результата? –