2017-08-06 72 views
0

我有一個數據幀df爲一組兩列計算餘弦相似度通過在數據幀

AID VID FID APerc VPerc 
1  A  X  0.2  0.5 
1  A  Z  0.1  0.3 
1  A  Y  0.4  0.9 
2  A  X  0.2  0.3 
2  A  Z  0.9  0.1 
1  B  Z  0.1  0.2 
1  B  Y  0.8  0.3 
1  B  W  0.5  0.4 
1  B  X  0.6  0.3 

我要計算的值APercVPerc所有對AIDVID的餘弦相似性。因此,對於上述結果應該是:

AID VID CosSim 
1  A  0.997 
2  A  0.514  
1  B  0.925  

我知道如何GROUPBY:df.groupby(['AID','VID'])

,我知道如何生成整個列餘弦相似:

from sklearn.metrics.pairwise import cosine_similarity 
cosine_similarity(df['APerc'], df['VPerc']) 

什麼是最好的和最快的方式來做到這一點,因爲我有一個非常大的文件。

回答

4

不知道這是最快groupby.apply通常是這樣做的方法:

(df.groupby(['AID','VID']) 
    .apply(lambda g: cosine_similarity(g['APerc'], g['VPerc'])[0][0])) 

#AID VID 
#1 A  0.997097 
#  B  0.924917 
#2 A  0.514496 
#dtype: float64 
+0

但使用這些方法不返回數據幀。我的意思是把as_index = False不讓我使用AID和VID作爲列。我需要他們作爲列,我需要餘弦相似性也是一個名稱,我可以打電話的列。我怎樣才能做到這一點? – BKS

+1

鏈'.rename('CosSim').setup_index()'後應該這樣做。 – Psidom

3

成對cosine_similarity是專爲二維數組,所以你需要做一些改造之前和之後。取而代之的是,使用SciPy的的cosine距離:上形狀的DF

from scipy.spatial.distance import cosine 
df.groupby(['AID','VID']).apply(lambda x: 1 - cosine(x['APerc'], x['VPerc'])) 
Out: 
AID VID 
1 A  0.997097 
    B  0.924917 
2 A  0.514496 
dtype: float64 

時序(10K,5)給出了用於sklearn SciPy的2.87ms和4.08ms。 4.08毫秒的相當數量可能是由於它輸出的警告,因爲與亞歷山大的版本,它下降到3.31毫秒。當我在一個2D數組上調用時,我懷疑sklearn版本會變得更快。

+1

@jezrael當然,讓我試試(很難得到結果時間,因爲警告) – ayhan

2

擴展@Psidom的解決方案,該系列計算cosine_similarity之前numpy的陣列,也重塑轉換:

(df.groupby(['AID','VID']) 
    .apply(lambda g: cosine_similarity(g['APerc'].values.reshape(1, -1), 
             g['VPerc'].values.reshape(1, -1))[0][0]))