Python的自学者,我正在尝试改进,因此非常欢迎任何帮助,非常感谢! 我想通过匹配另一列上的条件来计算我的数据框一列上的jaccard相似度。 df看起来像这样:
name bag number item quantity
sally 1 BANANA 3
sally 2 BREAD 1
franck 3 BANANA 2
franck 3 ORANGE 1
franck 3 BREAD 4
robert 4 ORANGE 3
jenny 5 BANANA 4
jenny 5 ORANGE 2
大约有80种商品,购物袋编号(样本)对于一位购物者而言是唯一的,但它们可以有多个,且数量在0到4之间。 我想遍历袋数,以将内容与每副袋的抽纸相似度或距离进行比较。如果可能,可以选择将数量作为比较的权重。 理想的结果是像这样的数据框 Python Pandas Distance matrix using jaccard similarity
我认为解决方案在这> How to compute jaccard similarity from a pandas dataframe 然后那个How to apply a custom function to groups in a dask dataframe, using multiple columns as function input
我想我应该遍历一个掩码来设置jaccard函数的两个变量。但是在我看到的每个示例中,要比较的项目都在不同的列中。 所以我有点迷茫,在这里... 非常感谢您的帮助! 欢呼
答案 0 :(得分:0)
可以通过以下步骤解决更简单,更重要的问题版本:
使用当前数据框创建一个pivot table
p = df.pivot_table(
index='bag_number',
columns='item',
values='quantity',
).fillna(0) # Convert NaN to 0
按照您的linked question中的示例使用scipy
from scipy.spatial.distance import jaccard, pdist, squareform
m = 1 - squareform(pdist(p.astype(bool), jaccard))
sim = pd.DataFrame(m, index=p.index, columns=p.index)
结果:
bag_number 1 2 3 4 5
bag_number
1 1.000000 0.000000 0.333333 0.000000 0.500000
2 0.000000 1.000000 0.333333 0.000000 0.000000
3 0.333333 0.333333 1.000000 0.333333 0.666667
4 0.000000 0.000000 0.333333 1.000000 0.500000
5 0.500000 0.000000 0.666667 0.500000 1.000000
加权版本仅稍微复杂一点。 pdist
function仅支持将应用于所有比较的向量,因此您需要创建一个自定义相似度(或距离)函数。根据{{3}},加权版本可以计算如下:
import numpy as np
def weighted_jaccard_distance(x, y):
arr = np.array([x, y])
return 1 - arr.min(axis=0).sum() / arr.max(axis=0).sum()
现在您可以计算加权相似度
sim_weighted = pd.DataFrame(
data=1 - squareform(pdist(p, weighted_jaccard_distance)),
index=p.index,
columns=p.index,
)
结果:
bag_number 1 2 3 4 5
bag_number
1 1.00 0.000000 0.250000 0.000000 0.500000
2 0.00 1.000000 0.142857 0.000000 0.000000
3 0.25 0.142857 1.000000 0.111111 0.300000
4 0.00 0.000000 0.111111 1.000000 0.285714
5 0.50 0.000000 0.300000 0.285714 1.000000