如何在Python中计算Jaccard索引?
我有一个如下所示的数据集: 它显示哪本书是哪家商店卖的如何在Python中计算Jaccard索引?,python,pandas,machine-learning,Python,Pandas,Machine Learning,我有一个如下所示的数据集: 它显示哪本书是哪家商店卖的 import pandas as pd books = {'shop': ["A", "B", "C", "D", "E", "A", "B", "C", "D",], 'book_id': [1, 1, 2, 3, 3, 3, 4, 5, 1,] } df = pd.DataFrame(books, columns = ['shop', 'book_id']) 这是印刷品: shop book_
import pandas as pd
books = {'shop': ["A", "B", "C", "D", "E", "A", "B", "C", "D",],
'book_id': [1, 1, 2, 3, 3, 3, 4, 5, 1,]
}
df = pd.DataFrame(books, columns = ['shop', 'book_id'])
这是印刷品:
shop book_id
0 A 1
1 B 1
2 C 2
3 D 3
4 E 3
5 A 3
6 B 4
7 C 5
8 D 1
在数据集中
- 商店A销售1,3
- 商店B出售1,4
- 商店C出售2,5
- 商店D销售3,1
- 商店E只卖3个
result = {'shop_1': ["A", "B", "A", "C", "A", "D", "A", "E",],
'shop_2': ["B", "A", "C", "A", "D", "A", "E", "A",],
'jaccard': [33.3, 33.33, 0, 0, 100, 100, 50, 50,]
}
desired_df = pd.DataFrame(result, columns = ['shop_1', 'shop_2', 'jaccard'])
有人能帮我做这个吗?是否有实现Jaccard索引的库 如果数据不太大,可以使用广播方式:
books = pd.crosstab(df.shop, df.book_id)
# underlying numpy
arr = books.values
common = (arr[None,...] | arr[:,None,:]).sum(-1)
output = (books @ books.T)/common
输出:
shop A B C D E
shop
A 1.000000 0.333333 0.0 1.000000 0.5
B 0.333333 1.000000 0.0 0.333333 0.0
C 0.000000 0.000000 1.0 0.000000 0.0
D 1.000000 0.333333 0.0 1.000000 0.5
E 0.500000 0.000000 0.0 0.500000 1.0
shop_1 shop_2 jaccard
1 A B 0.333333
2 A C 0.000000
3 A D 1.000000
4 A E 0.500000
5 B A 0.333333
7 B C 0.000000
8 B D 0.333333
9 B E 0.000000
10 C A 0.000000
11 C B 0.000000
13 C D 0.000000
14 C E 0.000000
15 D A 1.000000
16 D B 0.333333
17 D C 0.000000
19 D E 0.500000
20 E A 0.500000
21 E B 0.000000
22 E C 0.000000
23 E D 0.500000
要匹配您的预期输出:
output = (output.stack().rename_axis(['shop_1','shop_2'])
.reset_index(name='jaccard')
.query('shop_1 != shop_2')
)
输出:
shop A B C D E
shop
A 1.000000 0.333333 0.0 1.000000 0.5
B 0.333333 1.000000 0.0 0.333333 0.0
C 0.000000 0.000000 1.0 0.000000 0.0
D 1.000000 0.333333 0.0 1.000000 0.5
E 0.500000 0.000000 0.0 0.500000 1.0
shop_1 shop_2 jaccard
1 A B 0.333333
2 A C 0.000000
3 A D 1.000000
4 A E 0.500000
5 B A 0.333333
7 B C 0.000000
8 B D 0.333333
9 B E 0.000000
10 C A 0.000000
11 C B 0.000000
13 C D 0.000000
14 C E 0.000000
15 D A 1.000000
16 D B 0.333333
17 D C 0.000000
19 D E 0.500000
20 E A 0.500000
21 E B 0.000000
22 E C 0.000000
23 E D 0.500000
Scipy可能会有所帮助:谢谢@PrateekDewan,我试图通过手动键入示例数据来实现它,但由于我是Python的初学者,很难操纵真实数据。非常感谢@Quany Hoang。请允许我问一下‘a’在这里代表什么:common=(a[None,…]| a[:,None,:])。sum(-1)错过了重构,它是上面定义的numpy数组。请参阅更新。Hi@Quang Hoang,我刚刚尝试使用我的真实数据,但不幸的是,内核在运行时已死亡:pd.crosstab(df.shop,df.book_id)你认为这是因为我的数据很大(980 MB)吗?你建议我怎么解决这个问题?@datazang你的数据太大了。你有多少唯一的图书id/商店?有2900万个图书id,但我试图获得类别id(240K)而不是图书id。内核仍在消亡@广亨