【问题标题】:Create dataframe column with cosine distance between each row and a vector使用每行和向量之间的余弦距离创建数据框列
【发布时间】:2020-01-14 12:49:38
【问题描述】:

我有以下数据框:

file_1  0.797647  ...  0.000000
file_2  0.000000  ...  0.000000
file_3  0.000000  ...  0.000000

我们称之为df。 每行都有一个索引 (file_x) 和 4096 列(没有名称)。

我还有一个大小为 4096 的向量(称为 test_file),我想计算 df 中每一行的余弦相似度。 基本思想是将结果附加到一个新列中,我可以对其进行排序以获得最好的 5 个结果。

到目前为止,我一直在使用iterrows() 在我的向量和每一行之间执行cosine_similarity 测量。

for index, row in df.iterrows():
    cos_sim = cosine_similarity(row.values.reshape(1, -1), test_file)

但对于性能问题,我想使用更适合矩阵计算的 pandas 或 numpy 方法。

我正在查看使用 lambda 函数的 .apply().assign() 方法,但我不知道如何继续(所有示例都使用我没有的命名列)。

我想做类似的事情

df.assign(cos_sim = cosine_similarity(df[:], test_file))

但是如何让当前行对相似度进行操作呢?

我还使用 df["cos_dist"] = cdist(np.stack(df.vector), test_file, metric="cosine") 之类的东西从 scipy 库中调查了 cdist,但我不知道如何保留原始数据框中的索引信息。

【问题讨论】:

  • 您可以使用 axis=1 参数在行上应用
  • 是的,但是您如何定义要应用的功能?我需要使用每行中的所有列作为向量与我的test_file 向量进行比较。
  • 试试lambda row: cosine_similarity(row.values.reshape(1, -1), test_file)

标签: python pandas


【解决方案1】:

不需要apply,让sklearn对整个数组进行计算:

df['cos_sim'] = cosine_similarity(df, test_file).reshape(-1)

例子:

import pandas as pd, numpy as np
from sklearn.metrics.pairwise import cosine_similarity

n,m = 4,3
np.random.seed(0)
df = pd.DataFrame(np.random.randn(m,n), index=['file_{}'.format(i) for i in range(1,m+1)])
test_file = np.random.randn(1,n)

df['cos_sim'] = cosine_similarity(df, test_file).reshape(-1)
print(df)

#               0         1         2         3   cos_sim
#file_1  1.764052  0.400157  0.978738  2.240893  0.890653
#file_2  1.867558 -0.977278  0.950088 -0.151357  0.760393
#file_3 -0.103219  0.410599  0.144044  1.454274  0.360205

【讨论】:

    猜你喜欢
    • 2021-07-15
    • 2020-02-11
    • 2018-03-21
    • 2016-11-29
    • 2016-08-23
    • 2014-09-30
    • 1970-01-01
    • 2021-08-18
    • 1970-01-01
    相关资源
    最近更新 更多