我有3个数据框,每个数据框按位置(前锋,后卫和守门员)列出了一个球员列表:
FWD_df = pd.DataFrame({'name':['Keno','Pepê','Rhuan','Léo Natel','Pedro Raul','Wesley'],
'team':['Atlético-MG','Grêmio','Botafogo','Corinthians','Botafogo','Palmeiras'],
'adversary':['Fluminense','Botafogo','Grêmio','Athlético-PR','Grêmio','Coritiba'],
'position':['FWD', 'FWD', 'FWD', 'FWD', 'FWD', 'FWD'],
'open_price':[15.75, 14.05, 3.51, 5.83, 5.92, 4.25]})
MID_df = pd.DataFrame({'apelido':['Everton Ribeiro','Thiago Galhardo','Thiago Neves','Mateus Vital','Dodi','Zé Gabriel'],
'clube':['Flamengo','Internacional','Sport','Corinthians','Fluminense', 'Internacional'],
'adversário':['Bragantino','Sport','Internacional','Athlético-PR','Atlético-MG','Sport'],
'posicao':['MID', 'MID', 'MID','MID', 'MID', 'MID'],
'preco_open':[10.82, 6.46, 4.96, 8.20, 5.29, 7.88]}).sort_values('preco_open', ascending=False).reset_index(drop=True).copy()
WING_df = pd.DataFrame({'apelido':['Renê','Abner Vinícius','Marcos Rocha','Victor Luis','Fagner','Ramon'],
'clube':['Flamengo','Athlético-PR','Palmeiras','Botafogo','Corinthians', 'Flamengo'],
'adversário':['Bragantino','Corinthians','Coritiba','Grêmio','Athlético-PR','Bragantino'],
'posicao':['WING', 'WING', 'WING','WING', 'WING', 'WING'],
'preco_open':[10.82, 6.46, 4.96, 8.20, 5.29, 7.88]}).sort_values('preco_open', ascending=False).reset_index(drop=True).copy()
DEF_df = pd.DataFrame({'name':['Pedro Geromel','Felipe Melo','Pedro Henrique','Réver','Thiago Heleno','Lucas Veríssimo'],
'team':['Grêmio','Palmeiras','Athlético-PR','Atlético-MG','Athlético-PR', 'Santos'],
'adversary':['Botafogo','Coritiba','Corinthians','Fluminense','Corinthians','Atlético-GO'],
'position':['DEF', 'DEF', 'DEF','DEF', 'DEF', 'DEF'],
'open_price':[10.82, 6.46, 4.96, 8.20, 5.29, 7.88]})
GKP_df = pd.DataFrame({'name':['Jandrei','Jean','Muriel','Diego Cavalieri','Marcelo Lomba','Luan Polli'],
'team':['Athlético-PR','Atlético-GO','Fluminense','Botafogo','Internacional', 'Sport'],
'adversary':['Corinthians','Santos','Atlético-MG','Grêmio','Sport','Internacional'],
'position':['GKP', 'GKP', 'GKP','GKP', 'GKP', 'GKP'],
'open_price':[8.73, 8.88, 5.66, 5.70, 10.62, 4.00]})
然后我为这些选定的玩家创建一个池,如下所示:
dfs = [FWD_df, DEF_df, GKP_df]
pool = pd.concat(dfs)
print (pool)
打印:
name team adversary position open_price
0 Keno Atlético-MG Fluminense FWD 15.75
1 Pepê Grêmio Botafogo FWD 14.05
2 Rhuan Botafogo Grêmio FWD 3.51
3 Léo Natel Corinthians Athlético-PR FWD 5.83
4 Pedro Raul Botafogo Grêmio FWD 5.92
5 Wesley Palmeiras Coritiba FWD 4.25
0 Pedro Geromel Grêmio Botafogo DEF 10.82
1 Felipe Melo Palmeiras Coritiba DEF 6.46
2 Pedro Henrique Athlético-PR Corinthians DEF 4.96
3 Réver Atlético-MG Fluminense DEF 8.20
4 Thiago Heleno Athlético-PR Corinthians DEF 5.29
5 Lucas Veríssimo Santos Atlético-GO DEF 7.88
0 Jandrei Athlético-PR Corinthians GKP 8.73
1 Jean Atlético-GO Santos GKP 8.88
2 Muriel Fluminense Atlético-MG GKP 5.66
3 Diego Cavalieri Botafogo Grêmio GKP 5.70
4 Marcelo Lomba Internacional Sport GKP 10.62
5 Luan Polli Sport Internacional GKP 4.00
规则:
我无法让前三名前锋面对一名两名前两名防守球员或一名前锋守门员 >,例如,如果他是他的下一个“对手”,则这样:
name team adversary position open_price
2 Rhuan Botafogo Grêmio FWD 3.51
...
0 Pedro Geromel Grêmio Botafogo DEF 10.82
这种情况发生时,我需要将最有价值的参与者(最高的“ open_price”)保留在其行位置,并将最便宜的参与者移至其最后分组的行索引。
在上述情况下,防御者的费用更高,因此他留在原地,我们将FWD向下移动到其位置的最后一个索引:
name team adversary position open_price
0 Keno Atlético-MG Fluminense FWD 15.75
1 Pepê Grêmio Botafogo FWD 14.05
2 Léo Natel Corinthians Athlético-PR FWD 5.83
3 Pedro Raul Botafogo Grêmio FWD 5.92
4 Wesley Palmeiras Coritiba FWD 4.25
5 Rhuan Botafogo Grêmio FWD 3.51 <---- was index 2, now 5
0 Pedro Geromel Grêmio Botafogo DEF 10.82
1 Felipe Melo Palmeiras Coritiba DEF 6.46
2 Pedro Henrique Athlético-PR Corinthians DEF 4.96
3 Réver Atlético-MG Fluminense DEF 8.20
4 Thiago Heleno Athlético-PR Corinthians DEF 5.29
5 Lucas Veríssimo Santos Atlético-GO DEF 7.88
0 Jandrei Athlético-PR Corinthians GKP 8.73
1 Jean Atlético-GO Santos GKP 8.88
2 Muriel Fluminense Atlético-MG GKP 5.66
3 Diego Cavalieri Botafogo Grêmio GKP 5.70
4 Marcelo Lomba Internacional Sport GKP 10.62
5 Luan Polli Sport Internacional GKP 4.00
但是,这样做之后,我们将在前三名中拥有一个将面对守门员的前锋,这也是规则所禁止的:
name team adversary position open_price
2 Léo Natel Corinthians Athlético-PR FWD 5.83
...
0 Jandrei Athlético-PR Corinthians GKP 8.73
由于守门员比前锋花费更多,所以他留在原地,我们将前锋下移,就像这样:
name team adversary position open_price
0 Keno Atlético-MG Fluminense FWD 15.75
1 Pepê Grêmio Botafogo FWD 14.05
2 Pedro Raul Botafogo Grêmio FWD 5.92
3 Wesley Palmeiras Coritiba FWD 4.25
4 Rhuan Botafogo Grêmio FWD 3.51 <---- was index 5, now 4
5 Léo Natel Corinthians Athlético-PR FWD 5.83 <---- was index 2, now 5
0 Pedro Geromel Grêmio Botafogo DEF 10.82
1 Felipe Melo Palmeiras Coritiba DEF 6.46
2 Pedro Henrique Athlético-PR Corinthians DEF 4.96
3 Réver Atlético-MG Fluminense DEF 8.20
4 Thiago Heleno Athlético-PR Corinthians DEF 5.29
5 Lucas Veríssimo Santos Atlético-GO DEF 7.88
0 Jandrei Athlético-PR Corinthians GKP 8.73
1 Jean Atlético-GO Santos GKP 8.88
2 Muriel Fluminense Atlético-MG GKP 5.66
3 Diego Cavalieri Botafogo Grêmio GKP 5.70
4 Marcelo Lomba Internacional Sport GKP 10.62
5 Luan Polli Sport Internacional GKP 4.00
再次,我们将不得不再次执行此操作:
name team adversary position open_price
0 Keno Atlético-MG Fluminense FWD 15.75
1 Pepê Grêmio Botafogo FWD 14.05
2 Wesley Palmeiras Coritiba FWD 4.25 <---- was index 3, now 2
3 Rhuan Botafogo Grêmio FWD 3.51 <---- was index 4, now 3
4 Léo Natel Corinthians Athlético-PR FWD 5.83 <---- was index 5, now 4
5 Pedro Raul Botafogo Grêmio FWD 5.92 <---- was index 3, now 5
0 Pedro Geromel Grêmio Botafogo DEF 10.82
1 Felipe Melo Palmeiras Coritiba DEF 6.46
2 Pedro Henrique Athlético-PR Corinthians DEF 4.96
3 Réver Atlético-MG Fluminense DEF 8.20
4 Thiago Heleno Athlético-PR Corinthians DEF 5.29
5 Lucas Veríssimo Santos Atlético-GO DEF 7.88
0 Jandrei Athlético-PR Corinthians GKP 8.73
1 Jean Atlético-GO Santos GKP 8.88
2 Muriel Fluminense Atlético-MG GKP 5.66
3 Diego Cavalieri Botafogo Grêmio GKP 5.70
4 Marcelo Lomba Internacional Sport GKP 10.62
5 Luan Polli Sport Internacional GKP 4.00
直到我们最终得到上面的数据框,即最终池。
该如何对行进行有条件的重新排序?有人可以在这里向我指出正确的方向吗?
答案 0 :(得分:1)
您有一个问题,需要根据约束条件找到一个平衡点。
我在这里提出一个不使用python3 -m pip install --upgrade pip
的解决方案,而是使用纯python列表,因为熊猫的开销只会减慢解决方案的速度。
首先,显然存在无限循环的可能性。因此,您必须跟踪过去的排列配置,以便知道何时绕圈并开始循环。
我创建了一个自定义错误pandas
(出于可读性),只要发生这种情况就会引发该错误。其余代码应该很简单。
InfeasableError
Setup
现在,平衡发现函数:
class InfeasableError(Exception):
pass
# These are the positions on the lists for team, adv and prices.
TEAM_POS = 2
ADVERSARY_POS = 3
PRICE_POS = 5
fwd = FWD_df.reset_index().values.tolist()
dfs = DEF_df.reset_index().values.tolist()
gkp = GKP_df.reset_index().values.tolist()
mid = MID_df.reset_index().values.tolist()
wig = WING_df.reset_index().values.tolist()
该解决方案可以随时将其导入熊猫:
def find_equilibrium(fwd, dfs, gkp, mid, wig, configs):
''' Finds an equilibrium for forward, defense and goalkeeper players.
'''
initial_config = get_config(fwd, dfs, gkp) # Initial configuration
# Below is the logic for FWD-DEF equilibria.
for i, fwd_player in enumerate(fwd[:3]):
for j, def_player in enumerate(dfs[:2]):
if fwd_player[ADVERSARY_POS] == def_player[TEAM_POS]:
if fwd_player[PRICE_POS] < def_player[PRICE_POS]:
del fwd[i]
fwd.append(fwd_player)
else:
del dfs[j]
dfs.append(def_player)
# Below is the logic for FWD-GKP equilibria.
gkp_player = gkp[0]
for i, fwd_player in enumerate(fwd[:3]):
if fwd_player[ADVERSARY_POS] == gkp_player[TEAM_POS]:
if fwd_player[PRICE_POS] < gkp_player[PRICE_POS]:
del fwd[i]
fwd.append(fwd_player)
else:
del gkp[0]
gkp.append(gkp_player)
final_config = get_config(fwd, dfs, gkp)
if initial_config == final_config:
# This means nothing changed. Equilibrium found!
return [*fwd, *dfs, *gkp]
if final_config in configs:
raise InfeasableError("There's no solution for an equilibrium.")
configs.append(final_config)
return find_equilibrium(fwd, dfs, gkp, mid, wig, configs)
def get_config(fwd, dfs, gkp):
''' Returns an ordered configuration of integers.
Each integer represents a unique player, and each sequence represents
a specific configuration of how these players are arranged.
'''
return (fwd[0][0], fwd[1][0], fwd[2][0], dfs[0][0], dfs[1][0], gkp[0][0])
solution = find_equilibrium(fwd, dfs, gkp, mid, wig, [])
>>> pd.DataFrame(solution)