我有一个看起来像这样的数据框:
api_spec_id label Paths_modified Tags_modified Endpoints_added
933 803.0 minor 8.0 3.0 6
934 803.0 patch 0.0 4.0 2
935 803.0 patch 3.0 1.0 0
938 803.0 patch 10.0 0.0 4
939 803.0 patch 3.0 5.0 1
940 803.0 patch 6.0 0.0 0
942 803.0 patch 0.0 6.0 2
946 803.0 patch 3.0 2.0 3
947 803.0 patch 0.0 0.0 1
我想计算每一行之间的逐行余弦相似度。数据框已经在
api_spec_id
和date
上排序。
预期的输出应该是这样的(值不准确):
api_spec_id label Paths_modified Tags_modified Endpoints_added Distance
933 803.0 minor 8.0 3.0 6 ...
934 803.0 patch 0.0 4.0 2 1.00234
935 803.0 patch 3.0 1.0 0
938 803.0 patch 10.0 0.0 4
939 803.0 patch 3.0 5.0 1
940 803.0 patch 6.0 0.0 0
942 803.0 patch 0.0 6.0 2
946 803.0 patch 3.0 2.0 3
947 803.0 patch 0.0 0.0 1
我试着查看堆栈溢出中的解决方案,但用例似乎在所有情况下都有点不同。我还有更多功能,总共大约 32 个,我想考虑所有这些功能列(修改的路径、修改的标签和在上面的 df 中添加的端点是一些功能的示例),并计算每行的距离度量。
这是我能想到的,但它没有达到目的:
df = pd.DataFrame(np.random.randint(0, 5, (3, 5)), columns=['id', 'commit_date', 'feature1', 'feature2', 'feature3'])
similarity_df = df.iloc[:, 2:].apply(lambda x: cosine_similarity([x], df.iloc[:, 2:])[0], axis=1)
有人对我如何进行这件事有什么建议吗?
编辑:在我的用例中一个可能的障碍是我无法摆脱我的其他列,我仍然需要至少保留
api_spec_id
以提供一种将距离映射回原始数据框的方法。
这可以在没有
apply
(更快)的情况下完成:
import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.randint(0, 5, (3, 5)), columns=['id', 'commit_date', 'feature1', 'feature2', 'feature3'])
# Calculate L2 norm of features in row
df["l2norm"] = np.linalg.norm(df.loc[:, "feature1":"feature3"], axis=1)
# Create shifted dataframe
df2 = df.shift(1, fill_value=0)
# Dot product of current with previous row
dot_product = (df.loc[:, "feature1":"feature3"] * df2.loc[:, "feature1":"feature3"]).sum(axis=1)
# L2 norm product of current and previous row
norm_product = df["l2norm"] * df2["l2norm"]
# Divide and print
print(dot_product / norm_product)
cosine_similarity
尝试这种方法
from sklearn.metrics.pairwise import cosine_similarity
import pandas as pd
df['Distance'] = (df.iloc[:, 2:]
.apply(lambda row: cosine_similarity([row],
[df.iloc[row.name - 1, 2:]])[0][0]
if row.name > 0 else None, axis=1))
print(df)
您也可以使用
for-loop
但要考虑数据框的大小
similarity_df = cosine_similarity(df.iloc[:, 2:])
df['Distance'] = ([None] + [similarity_df[i, i-1] for i in range(1, len(df))]
print(df)
Note 如果提供的代码没有产生您想要的输出,您可能必须通过包含
Distance
列的确切值来更新您的问题。