2017-08-06 49 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]))