Python高效的三向分层排序算法
我正在尝试实施一个(三方)打破平局的程序,你可能会在(美国)体育中看到。我想先按胜负排序,如果平局,则使用平局决胜法 我需要这是尽可能快的运行时,我真的不关心内存需求。如果有更好的方法来表示我的数据,那么这也是一个有用的答案 我想排序的数据最多有15个值,所以运行时在这方面还不错,我只想做10万次 伪代码如下所示:Python高效的三向分层排序算法,python,algorithm,sorting,Python,Algorithm,Sorting,我正在尝试实施一个(三方)打破平局的程序,你可能会在(美国)体育中看到。我想先按胜负排序,如果平局,则使用平局决胜法 我需要这是尽可能快的运行时,我真的不关心内存需求。如果有更好的方法来表示我的数据,那么这也是一个有用的答案 我想排序的数据最多有15个值,所以运行时在这方面还不错,我只想做10万次 伪代码如下所示: Iterator = 0 maxVal = max value of wins maxes = teams with wins == maxVal If len(maxes)
Iterator = 0
maxVal = max value of wins
maxes = teams with wins == maxVal
If len(maxes) == 1
rank[values] = iterator
iterator += 1
sort(restOfData)
Else
# H2Hwins computes the amount of wins for teams currently tied incase of 2 or more teams tied
counts = sorted([(h2hwins(t, maxes), pointDifferential) for team in maxes])
for c in counts
rank[value] = iterator
iterator += 1
sort(restOfData)
return rank
因此,如果我有以下输入,这些将是输出:
# Columns are Team, Wins, H2H Tiebreaks, Point Differential
# Lakers win tie based on H2H with Clippers
testData = [['Lakers', 48, ['Clippers'], 6], ['Clippers', 48, ['Warriors'], 8], ['Warriors', 47, ['Lakers'], 10]]
magicSort(testData)
>>> ['Lakers', 'Clippers', 'Warriors']
# Warriors have 2 H2H tiebreakers so they are 1st. Lakers have 1 H2H tiebreaker so they are 2nd.
testData2 = [['Lakers', 48, ['Clippers'], 6], ['Clippers', 48, [''], 8], ['Warriors', 48, ['Lakers', 'Clippers'], 10]]
magicSort(testData2)
>>> ['Warriors', 'Lakers', 'Clippers']
# All 3 are tied so we default to point differential
testData3 = [['Lakers', 47, ['Clippers'], 6], ['Clippers', 47, ['Warriors'], 8], ['Warriors', 47, ['Lakers'], 10]]
magicSort(testData3)
>>> ['Warriors', 'Clippers', 'Lakers']
如果需要,我可以提出更多的测试案例,但我相信这涵盖了边缘案例更新的答案:你想要一个排序算法,它可以按照你定义的字段顺序打破三方关系:a)赢b)H2H分接头的数量c)点差分 我建议您在任何时候都可以使用pandas来处理复杂的数据(比如像这样的多键排序)。 首先,我们必须将奇怪的数据格式(递归嵌套列表)转换为可用的形式,以构建数据帧:
- 四元组列表:
团队、胜利、H2H\u抢七、积分差异
- 请注意,
应该是一个元组,即使它的长度为1或0。严格地说,我们只关心它的长度(H2H_Tiebreaks
),而不关心它的内容Num\u H2H\u Ties
- 请注意,
- 然后我们对df.sort_值进行排序(按=['Wins','Num_H2H_Ties','Point_Differential'],升序=False)。底部代码:
- 如果您只想要获胜团队的行,请执行
.iloc[0]
- 如果您只想知道获胜团队的名称,请执行
.iloc[0,0]
- 如果您只想要获胜团队的行,请执行
import pandas as pd
cols = ['Team', 'Wins', 'H2H_Tiebreaks', 'Point_Differential']
# 1) Lakers win tie based on H2H with Clippers
dat = [('Lakers', 48, ('Clippers',), 6), ('Clippers', 48, ('Warriors',), 8), ('Warriors', 47, ('Lakers',), 10)]
df1 = pd.DataFrame(data=dat, columns=cols)
# 2) Warriors have 2 H2H tiebreakers so they are 1st. Lakers have 1 H2H tiebreaker so they are 2nd.
dat2 = [('Lakers', 48, ('Clippers',), 6), ('Clippers', 48, (), 8), ('Warriors', 48, ('Lakers', 'Clippers'), 10)]
df2 = pd.DataFrame(data=dat2, columns=cols)
# 3) All 3 are tied so we default to point-differential
dat3 = [('Lakers', 47, ('Clippers',), 6), ('Clippers', 47, ('Warriors',), 8), ('Warriors', 47, ('Lakers',), 10)]
df3 = pd.DataFrame(data=dat3, columns=cols)
############
df1['Num_H2H_Ties'] = df1['H2H_Tiebreaks'].apply(len)
df1.sort_values(by=['Wins','Num_H2H_Ties', 'Point_Differential'], ascending=False)
# Result:
Team Wins H2H_Tiebreaks Point_Differential Num_H2H_Ties
1 Clippers 48 (Warriors,) 8 1
0 Lakers 48 (Clippers,) 6 1
2 Warriors 47 (Lakers,) 10 1
############
df2['Num_H2H_Ties'] = df2['H2H_Tiebreaks'].apply(len)
df2.sort_values(by=['Wins','Num_H2H_Ties', 'Point_Differential'], ascending=False)
# Result:
Team Wins H2H_Tiebreaks Point_Differential Num_H2H_Ties
2 Warriors 48 (Lakers, Clippers) 10 2
0 Lakers 48 (Clippers,) 6 1
1 Clippers 48 () 8 0
############
df3['Num_H2H_Ties'] = df3['H2H_Tiebreaks'].apply(len)
df3.sort_values(by=['Wins','Num_H2H_Ties', 'Point_Differential'], ascending=False)
# Result:
Team Wins H2H_Tiebreaks Point_Differential Num_H2H_Ties
2 Warriors 47 (Lakers,) 10 1
1 Clippers 47 (Warriors,) 8 1
0 Lakers 47 (Clippers,) 6 1
作为一项功能:
def sort_nway_tiebreaker(df):
# Filter only teams with max-Wins
df = df[df['Wins'] == df['Wins'].max()]
df['Num_H2H_Ties'] = df['H2H_Tiebreaks'].apply(len)
df = df.sort_values(by=['Wins','Num_H2H_Ties', 'Point_Differential'], ascending=False)
return df.iloc[0]
顺便说一下,您的输入数据格式非常奇怪,它是一个递归嵌套列表,而不是元组列表。你到底为什么要用那种格式,处理起来会很痛苦?它是从铲运机还是别的什么东西来的?所以,如果三队平局,这种方法就行不通了。@qwertylpc:没想到,OP只问了一个双向平局者;我不知道美国体育能产生三方关系。当然你可以推广这个方法,但是是的,它会很笨拙和不雅观,既然OP没有要求它,我就不打算编写代码了。但这是可以做到的。我是op。也许我有点不清楚,因为这是问题的一部分。最后一个例子是将它们全部打成三条领带抱歉由于解决了n条领带,您的问题比乍一看要复杂得多。我完全修改了我的答案。现在使用pandas
sort\u values()
方法而不是Python堆。