如何从我的 pandas 数据框中获取最多的对?

How to get the most pairs out of my pandas dataframe?

我有一个数据框,它为每一行显示一对人(name_1 和 name_2)以及相应的分数。分数是一个数值,表示这两个人的配合程度。分数越高,人 1 (name_1) 和人 2 (name_2) 之间的匹配度越好。

如您所见,有些名字可以找到两次或更多次。当然,一个人只能匹配一次。我的目标是,在数据框中找到尽可能多的对,并将它们中的每一个写入第二个数据框中。

让我纠结的问题是:

我想我可以得到最大。数据框中有 8 对,因为我在第一列中有 8 个不同的名称。不幸的是,最佳比赛的分数并没有明确区分。一个人可以匹配多个其他人,而其他人只能匹配一个特定的人。我对匹配分数不太感兴趣。我感兴趣的是不要因为对组合的错误选择而失去任何人。

我正在寻找一种方法来查找和提取尽可能多的数据帧对。

这是数据框 df:

      name_1     name_2  score
27      allen      jolly    1.8
23       anna       rock    2.8
22       anna  christina    1.1
26  christina       rock    2.3
24  christina      allen    1.4
25  christina      jolly    1.4
18      emily       rock    3.7
15      emily  sabastein    3.3
16      emily       anna    2.5
17      emily  christina    2.4
4       jacob      jolly    3.4
1       jacob       rick    2.9
3       jacob      allen    2.4
0       jacob       mary    2.3
2       jacob  christina    2.0
7        mary      jolly    1.7
5        mary       rick    1.4
6        mary  christina    1.3
14       rick       rock    2.8
9        rick  sabastein    2.8
8        rick      emily    2.5
13       rick      jolly    2.3
11       rick  christina    2.1
10       rick       anna    2.0
12       rick      allen    1.5
21  sabastein       rock    3.6
19  sabastein       anna    2.8
20  sabastein  christina    1.9

我认为就总最高分而言,最佳匹配是:

emely       rock        3.7
jacob       jolly       3.4
sabastein   anna        2.8
rick        allen       1.5
mary        christina   1.3 

我不确定这是否也是我可以获得的最大双数。如果您知道如何获得最佳配对(见上文)或最大配对数,我将非常高兴。

编辑
与此同时,我发现了一个非常方便的函数来从数据框创建图表,但是你应该将你的列 score 重命名为 weight 为此:
你可以简单地写:

G = nx.from_pandas_edgelist(df, 'name_1', 'name_2', 'weight')
mate = nx.max_weight_matching(G)

就是这样。
休息仍然是我们下面讨论的一部分,你如何进一步处理结果...


我的方法是

import pandas as pd
import networkx as nx

df['edges'] = df.apply(lambda r: (r.name_1, r.name_2, {'weight': r.score}), axis=1)

G = nx.Graph()

allnames = set(df.loc[:, ['name_1', 'name_2']].values.flatten())

for s in allnames:
    G.add_node(s)
G.add_edges_from(df.edges)

mate = nx.max_weight_matching(G)

结果:

res = pd.DataFrame(list(mate), columns=['name_1', 'name_2'])
res['score'] = res.apply(lambda r: G[r[0]][r[1]]['weight'], axis=1)

print(res)
print(f'\nMatchings: {len(res)}\nTotal Score: {res.score.sum():.1f}')            

#      name_1     name_2  score
#0       rock      emily    3.7                            
#1       rick  christina    2.1                          
#2       mary      jacob    2.3                            
#3  sabastein       anna    2.8                           
#4      jolly      allen    1.8                                             
#Matchings: 5                                                
#Total Score: 12.7      

文档来源:
为了设置图表,您已经有了正确的 link.
对于 maximum_matching 函数,请参见此处 https://networkx.github.io/documentation/networkx-1.10/reference/generated/networkx.algorithms.matching.max_weight_matching.html#networkx.algorithms.matching.max_weight_matching