2017-05-25 71 views
1

我正在實現一種聚類算法,它需要計算每對數據點之間的距離,其中每個數據點作爲一行存儲在pd.Dataframe中。總計算按O(n^2)的順序增長,我必須小心謹慎地做到這一點。大熊貓數據框每兩行的組合

什麼是做我想做的有效方式?

說我在一個數據幀有4個數據點:

#<inputtable tin> 
Id Label 
0  Michael 
1  Jim 
2  Pam 
3  Dwight 

,我需要運行一個定製的功能similar(x,y)來計算每兩個點組合(2,4)〜6之間的折扣,我的輸出應如:

#<outputtable tout> 
Source_Id Source_Label To_Id To_Label distance 
0   Michael   1  Jim   f('Michael', 'Jim') 
0   Michael   2  Pam   f('Michael', 'Pam') 
0   Michael   3  Dwight  f('Michael', 'Dwight') 
1   Jim    2  Pam   f('Jim', 'Pam') 
1   Jim    3  Dwight  f('Jim', 'Dwight') 
2   Pam    3  Dwight  f('Pam', 'Dwight') 

我做了什麼:

我試圖用pd.merge生成笛卡爾積爲表

data = pd.DataFrame([[0, 'Michael'], [1, 'Jim'], [2, 'Pam'], [3, 'Dwight']], columns=['Id', 'Label']) 
data['tmp'] = 1 
result = pd.merge(data, data, left_on='tmp', right_on='tmp') 
result = result[result['Id_x'] != result['Id_y']] 
print result 

然而,這看起來真的很像一個黑客合併,我也試過itertools與Pandas不能很好地工作。

任何人都知道採用自定義類似距離函數進行這種「聚類工作」的更有效方法嗎?我也計劃在Gephi中分析這個問題,我不知道一般情況下是否有更好的解決方案。

回答

1

首先
我不能解決爲O(n^2)問題。

itertools.combination

from itertools import combinations 

labels = df.Label.values.tolist() 

f = lambda x, y: x + y 

pd.Series({k: f(*k) for k in combinations(labels, 2)}) 

np.triu_indices

labels = df.Label.values 

f = lambda x, y: x + y 

i, j = np.triu_indices(labels.size, 1) 

combs = list(zip(labels[i], labels[j])) 

pd.MultiIndex.from_tuples(combs).to_series().apply(lambda t: f(*t))