计算数据帧中组中两列的余弦相似度

时间:2017-08-06 19:38:25

标签: python pandas dataframe cosine-similarity

我有一个数据框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     

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

我知道如何为整列生成余弦相似度:

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

这是最好和最快的方法,因为我有一个非常大的文件。

3 个答案:

答案 0 :(得分:4)

成对cosine_similarity专为2D数组而设计,因此您需要在之前和之后进行一些重塑。而不是那样,使用scipy的cosine距离:

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

df形状(10k,5)的时间为scipy提供2.87ms,为sklearn提供4.08ms。 4.08ms的相当数量可能是由于它输出的警告,因为亚历山大的版本下降到3.31ms。我怀疑在单个2D阵列上调用时,sklearn版本变得更快。

答案 1 :(得分: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

答案 2 :(得分:2)

扩展@Psidom的解决方案,在计算(df.groupby(['AID','VID']) .apply(lambda g: cosine_similarity(g['APerc'].values.reshape(1, -1), g['VPerc'].values.reshape(1, -1))[0][0])) 之前将系列转换为numpy数组,并重构:

vlcControl.TimeChanged += vlcControl_VideoOutChanged;

private void vlcControl_VideoOutChanged(object sender, VlcMediaPlayerTimeChangedEventArgs e)
{
    vlcControl.Audio.Volume = volume;
}