在熊猫分组中选择一个

我正在尝试创建所有可能的球员配对组合,以根据障碍类型 A、B、C 或 D 分配到 4 人高尔夫球队。


我尝试了各种 itertools 方法,例如组合和排列,但无法找出正确的方法。


from itertools import combinations, product, permutations

g = player_df.groupby(by = 'hcp_ABCD')

teams_listoflists = [group[1].index for group in g]

teams_combo_ndx = [player for player in permutations(teams_listoflists, 4)]

这是我的熊猫表:


        handicap      name hcp_ABCD

0         24   Player1        D

1         21   Player2        D

2          8   Player3        B

3         14   Player4        C

4         20   Player5        D

5         13   Player6        C

6         -1   Player7        A

7          5   Player8        A

8          8   Player9        B

9          6  Player10        B

10        20  Player11        D

11        15  Player12        C

12         0  Player13        A

13        12  Player14        C

14         0  Player15        A

15        10  Player16        B

我希望输出是玩家组合(团队)的所有组合(不重复),这样每个团队都有一个类型 A、B、C 和 D。该输出可以是与上面按“选项”分组的类似表格。


编辑:为了清楚起见,我添加了这个输出示例。


                       A Player     B Player     C Player   D Player

    option 1  team1    Player7      Player3      Player4    Player1

              team2    Player8      Player9      Player6    Player2

              team3    Player13     Player10     Player12   Player5

              team4    Player15     Player16     Player14   Player11

上面的重点是,我正在尝试找到一个生成器,该生成器循环遍历每个障碍组中的所有球员组合,以便团队选项的组合清晰。


编辑#2 我已经确定此代码产生了所有潜在团队组合的组合:


g = df.groupby(by = 'hcp_ABCD')

combinations = [list(group[1].index) for group in g]

这将创建一个列表列表,其中包含列表 [0] 中的 A 玩家、列表 [1] 中的 B 玩家等。


这为所有可能的团队组合提供了一个索引器:


from itertools import product

options = [option for option in product(*combinations)]

但是,如何将这些分配到“选项”中(见上面的例子)并确保没有重复是我坚持的。


编辑#3 一个更简单的版本(考虑这个问题的方法)是使用以下集合:


A = ['A1', 'A2', 'A3', 'A4']

B = ['B1', 'B2', 'B3', 'B4']

C = ['C1', 'C2', 'C3', 'C4']

D=  ['D1', 'D2', 'D3', 'D4']

这基本上完成了上面 groupby 所做的事情(按 hcp_ABCD 分组),但命名每个“A Player”、“B Player”等。


可能的团队组合:


team_combinations = [team for team in product(A, B, C, D)]

然后下一个技巧是将这些分配到 4 支球队的组合中,并且没有重复的球员。


拉莫斯之舞
浏览 137回答 3
3回答

MMMHUHU

感谢您澄清预期结果。这是我测试的答案。它可能不是您预期结果的确切格式,但我留给您修复它。import pandas as pddef is_duplicate_team(team, group):    '''check if an option already exists'''    return any(group == t for t in team)def is_player_exists(group, arr):    '''check if a player exists in a group'''    return any(x in g for g in group for x in arr)df = [         (24   ,'Player1','D'),         (21   ,'Player2','D'),          (8   ,'Player3','B'),         (14   ,'Player4','C'),         (20   ,'Player5','D'),         (13   ,'Player6','C'),         (-1   ,'Player7','A'),          (5   ,'Player8','A'),          (8   ,'Player9','B'),          (6  ,'Player10','B'),        (20  ,'Player11','D'),        (15  ,'Player12','C'),         (0  ,'Player13','A'),        (12  ,'Player14','C'),         (0  ,'Player15','A'),        (10  ,'Player16','B')]df = pd.DataFrame(df, columns=['handicap', 'name', 'hcp_ABCD'])from itertools import productgrouped = df.groupby('hcp_ABCD')['name'].apply(list).reset_index()df_name = [n for n in grouped.name]df_comb = [p for p in product(*df_name)]# below code will get all combinations of groups and for a team having all playersteams=[]for i in df_comb[:-1]:    group=[i]     for j in df_comb[1:]:         if not is_player_exists(group, j):            group.append(j)        if len(group) == 4:            if not is_duplicate_team(teams, group):                teams.append(group)            continue# below code will print the output similar to what you expectedi=0for t in teams:    i+=1    print('option: ', str(i) )    for p in t:        print(p)

眼眸繁星

我在评论中提出了建议。这是一个实现:import pandas as pdfrom functools import reducedata = [    (24,'Player1','D'),    (21,'Player2','D'),    (8,'Player3','B'),    (8,'Player4','B'),    (14,'Player5','C'),    (13,'Player6','C'),    (-1,'Player7','A'),    (5,'Player8','A')]df = pd.DataFrame(    data,    columns=['handicap', 'name', 'hcp_ABCD'])dfs = [    grp_df.drop(columns="hcp_ABCD")          .rename(columns={"name": f"player_{hndcp}",                           "handicap": f"handicap_{hndcp}"})    for hndcp, grp_df in df.assign(key=1)                           .groupby("hcp_ABCD")]result = reduce(    lambda left, right: left.merge(right, how="outer", on="key"),    dfs).drop(columns="key")print(result)输出:    handicap_A player_A  handicap_B player_B  handicap_C player_C  handicap_D player_D0           -1  Player7           8  Player3          14  Player5          24  Player11           -1  Player7           8  Player3          14  Player5          21  Player22           -1  Player7           8  Player3          13  Player6          24  Player13           -1  Player7           8  Player3          13  Player6          21  Player24           -1  Player7           8  Player4          14  Player5          24  Player15           -1  Player7           8  Player4          14  Player5          21  Player26           -1  Player7           8  Player4          13  Player6          24  Player17           -1  Player7           8  Player4          13  Player6          21  Player28            5  Player8           8  Player3          14  Player5          24  Player19            5  Player8           8  Player3          14  Player5          21  Player210           5  Player8           8  Player3          13  Player6          24  Player111           5  Player8           8  Player3          13  Player6          21  Player212           5  Player8           8  Player4          14  Player5          24  Player113           5  Player8           8  Player4          14  Player5          21  Player214           5  Player8           8  Player4          13  Player6          24  Player115           5  Player8           8  Player4          13  Player6          21  Player2

GCT1015

下面的方法是使用笛卡尔积,然后分组两次,将玩家分配到具有一组独特障碍的团队中。import pandas as pdfrom pandas.compat import StringIOprint(pd.__version__)pd.options.display.max_rows = 664csvdata = StringIO("""handicap,name,hcp_ABCD24,Player1,D21,Player2,D8,Player3,B14,Player4,C20,Player5,D13,Player6,C-1,Player7,A5,Player8,A8,Player9,B6,Player10,B20,Player11,D15,Player12,C0,Player13,A12,Player14,C0,Player15,A10,Player16,B""")df=pd.read_csv(csvdata)# Generate all possible groups# https://stackoverflow.com/questions/53699012/performant-cartesian-product-cross-join-with-pandasdef cartesian_product(left, right):    return (left.assign(key=1).merge(right.assign(key=1), on='key').drop('key', 1))def distribute_players(x):    x['distribute'] = range(0, 4)    return xdf = cartesian_product(df, df.copy())df = df.groupby(['name_x', 'hcp_ABCD_y']).apply(distribute_players)df['team'] = df.groupby(['name_x', 'distribute']).ngroup()print(df[['handicap_y','name_y','hcp_ABCD_y','team']].sort_values(['team']))     handicap_y    name_y hcp_ABCD_y  team0            24   Player1          D     02             8   Player3          B     03            14   Player4          C     06            -1   Player7          A     01            21   Player2          D     15            13   Player6          C     17             5   Player8          A     18             8   Player9          B     1
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python