Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 计算数据帧中group by中两列的余弦相似性_Python_Pandas_Dataframe_Cosine Similarity - Fatal编程技术网

Python 计算数据帧中group by中两列的余弦相似性

Python 计算数据帧中group by中两列的余弦相似性,python,pandas,dataframe,cosine-similarity,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

我有一个数据帧
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
我想计算所有对
AID
VID
的值
APerc
的余弦相似性。因此,上述结果应为:

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'])

考虑到我有一个非常大的文件,最好和最快的方法是什么呢。

成对
余弦\u相似性
是为2D阵列设计的,因此您需要在前后进行一些重塑。使用scipy的
余弦
距离:

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)的测向仪上的计时,scipy为2.87ms,sklearn为4.08ms。相当一部分4.08毫秒可能是由于Alexander版本的警告下降到3.31毫秒。我怀疑sklearn版本在单个2D阵列上调用时会快得多。

不确定它是否是最快的,
groupby。应用通常是实现这一点的方法:

(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

扩展@Psidom的解决方案,在计算
余弦_相似性之前,将序列转换为numpy数组,并重塑:

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

但是,使用这些方法不会返回数据帧。我的意思是,将as_index=False设置为不允许我使用AID和VID作为列。我需要它们作为列,我需要余弦相似性,也就是一个可以调用名称的列。我该怎么做?Chain
。rename('CosSim')。reset_index()
之后应该怎么做。