2013-11-08 3 views
3

Мне нравится находить элемент DF2, который является клоэтом для элемента в DF1.Расчет минимального расстояния между двумя DataFrames

Расстояние до Евклида.

Например, для A в DF1 F в DF2 является кластером.

>>> DF1 
    X Y name 
0 1 2 A 
1 3 4 B 
2 5 6 C 
3 7 8 D 
>>> DF2 
    X Y name 
0 3 8 E 
1 2 4 F 
2 1 9 G 
3 6 4 H 

Мой код

DF1 = pd.DataFrame({'name' : ['A', 'B', 'C', 'D'],'X' : [1,3,5,7],'Y' : [2,4,6,8]}) 
DF2 = pd.DataFrame({'name' : ['E', 'F', 'G', 'H'],'X' : [3,2,1,6],'Y' : [8,4,9,4]}) 


def ndis(row): 
    try: 
     X,Y=row['X'],row['Y'] 
     DF2['DIS']=(DF2.X-X)*(DF2.X-X)+(DF2.Y-Y)*(DF2.Y-Y) 
     temp=DF2.ix[DF2.DIS.idxmin()] 
     return temp[2] #  print temp[2] 
    except: 
     pass   


DF1['Z']=DF1.apply(ndis, axis=1) 

Это прекрасно работает, и это займет слишком много времени для большого набора данных.

Другой вопрос заключается в том, как найти 2-й и 3-й клабели.

ответ

1

Там более чем один подход, например, можно использовать NumPy:

>>> xy = ['X', 'Y'] 
>>> distance_array = numpy.sum((df1[xy].values - df2[xy].values)**2, axis=1) 
>>> distance_array.argmin() 
1 

Top 3 ближе всего (не самый быстрый подход, я полагаю, но самый простой)

>>> distance_array.argsort()[:3] 
array([1, 3, 2]) 

Если скорость вызывают озабоченность, проводят тесты производительности.

1

Посмотрите на scipy.spatial.KDTree и связанный cKDTree, который работает быстрее, но предлагает только часть функциональности. Для больших наборов вы, вероятно, не будете бить это за скорость.

Смежные вопросы