Python 熊猫匹配算法

Python 熊猫匹配算法,python,pandas,Python,Pandas,比如说,我有一个这样的数据帧: affinity applicant_id job_id 1 a 7 b 7 c 5 2 a 0 b 4 c

比如说,我有一个这样的数据帧:

                     affinity
applicant_id job_id          
1            a              7
             b              7
             c              5
2            a              0
             b              4
             c              2
3            a              4
             b              8
             c              1
我需要将每个申请人与一份工作相匹配,以便(a)更高的亲和力是首选;(b) 没有一个申请人与一个以上的工作相匹配;(c) 没有一份工作与多个申请人匹配。在上面的例子中,我想得到

                     affinity
applicant_id job_id          
3            b              8
1            a              7
2            c              2
我能想到的最好的办法就是

tmp = candidates.sort_values(ascending=False).copy()
matches = []
while len(tmp):
    (applicant, job), affinity = next(tmp.iteritems())
    matches.append((applicant, job))
    tmp = tmp.loc[(tmp.index.get_level_values('applicant_id') != applicant)
                  & (tmp.index.get_level_values('job_id') != job)]
candidates.reindex(matches)

这可以在没有显式迭代的情况下在pandas中实现吗

像那样的怎么样

job['applicant_id'].fillna(method='ffill', inplace=True)
job_a = job.sort_values(['applicant_id', 'affinity'] , ascending=False).drop_duplicates(['applicant_id'], keep="first").drop_duplicates(['job_id'], keep="first")
job_a = job_a.append(job[~(job['applicant_id'].isin(list(job_a['applicant_id']))) & ~(job['job_id'].isin(list(job_a['job_id'])))])
print(job_a)
这是典型的

我们将制作矩阵,用一些荒谬的高惩罚来填充缺失的值,这样它们就永远不会匹配。只有当至少有一个工作人员与某个作业有关联时,该作业才会出现在此矩阵中,因此这将起作用

样本数据 代码 输出:

我们分配给每个人的工作比分配给每个人的都多,但有些工作仍然空缺。由于人数多于工作,一些低亲和力的人仍然没有得到分配

你的申请者数量与工作相同吗?@ALollz没有,但我对不匹配的申请者/工作没有意见。那么,每个申请者对每个工作都有亲和力吗?或者有一些申请人不能从事某些工作?@ALollz只有那些在
候选人中的配对才能被考虑。mew问了一个问题,为什么不能将2分配给b,3分配给c?这是多重指数,不是Nan。我不认为这达到了我想要的。即使在你的第二行,你也会得到重复的。示例:如果所有工作都将同一个候选人排在最高的位置,该怎么办?然后,
job\u a
将多次选中该候选人!这是一个不同的定义,从我的最佳匹配,但它仍然适用于me@BlindDriver为什么呢这将为您提供符合每个职务一名申请人约束的申请人职务组合的最大亲和力总和。正确。然而,我的算法不同。我选择了一个具有最高亲和力的匹配项,然后将该应聘者和该职位从匹配候选人列表中删除,直到没有匹配候选人留下为止;这是故意含糊不清的,因为我愿意接受任何合理的成本函数。
from scipy import optimize
import pandas as pd

df = pd.DataFrame({'applicant_id': [1]*3 + [2]*3 + [3]*3 + [4],
                   'job_id': ['a', 'b', 'c']*3 + ['h'],
                   'affinity': [7,7,5,0,4,2,4,8,1,10]})
df1 = df.pivot(index='applicant_id', columns='job_id', values='affinity').fillna(-10**8)
#job_id                  a            b            c            h
#applicant_id                                                    
#1                     7.0          7.0          5.0 -100000000.0
#2                     0.0          4.0          2.0 -100000000.0
#3                     4.0          8.0          1.0 -100000000.0
#4            -100000000.0 -100000000.0 -100000000.0         10.0

opt = optimize.linear_sum_assignment(df1.to_numpy()*-1)
pd.DataFrame(df1.lookup(df1.index[opt[0]], df1.columns[opt[1]]), 
             columns=['affinity'],
             index=pd.MultiIndex.from_arrays([df1.index[opt[0]], df1.columns[opt[1]]]))
                     affinity
applicant_id job_id          
1            a            7.0
2            c            2.0
3            b            8.0
4            h           10.0