【问题标题】:Sequentially extract top n from group depending on group value根据组值顺序从组中提取前 n 个
【发布时间】:2021-12-30 14:07:53
【问题描述】:

我正在计算一些足球数据。

我有以下数据框:

{'Player': {8: 'Darrel Williams',  2: 'Mark Ingram',  3: 'Michael Carter',  4: 'Najee Harris',  10: 'James Conner',  0: 'Buffalo Bills',  15: 'Davante Adams',  1: 'Aaron Rodgers',  5: 'Tyler Bass',  11: 'Corey Davis',  6: 'Van Jefferson',  14: 'Matt Ryan',  7: 'T.J. Hockenson',  9: 'Antonio Brown',  12: 'Alvin Kamara',  13: 'Tyler Boyd'}, 'Position': {8: 'RB',  2: 'RB',  3: 'RB',  4: 'RB',  10: 'RB',  0: 'DEF',  15: 'WR',  1: 'QB',  5: 'K',  11: 'WR',  6: 'WR',  14: 'QB',  7: 'TE',  9: 'WR',  12: 'RB',  13: 'WR'}, 'Score': {8: 24.9,  2: 18.8,  3: 16.2,  4: 15.3,  10: 13.9,  0: 12.0,  15: 11.3,  1: 10.48,  5: 9.0,  11: 8.8,  6: 6.9,  14: 1.68,  7: 0.0,  9: 0.0,  12: 0.0,  13: 0.0}}
Player Position Score
Darrel Williams RB 24.9
Mark Ingram RB 18.8
Michael Carter RB 16.2
Najee Harris RB 15.3
James Conner RB 13.9
Buffalo Bills DEF 12
Davante Adams WR 11.3
Aaron Rodgers QB 10.48
Tyler Bass K 9
Corey Davis WR 8.8
Van Jefferson WR 6.9
Matt Ryan QB 1.68
T.J. Hockenson TE 0
Antonio Brown WR 0
Alvin Kamara RB 0
Tyler Boyd WR 0

鉴于以下requirements_dictionary,我要做的是为每个key(数据框中的Position)提取顶部value(数据框中的Score):

requirements_dictionary = {'QB': 1, 'RB': 2, 'WR': 2, 'TE': 1, 'K': 1, 'DEF': 1, 'FLEX': 2}

让这变得具有挑战性的是,对于最终的 keyFLEX,它与 数据框中的任何位置相匹配,因为该值 可能是位置:RB, WR,TE

最终输出应如下所示:

Player Position Score
Darrel Williams RB 24.9
Mark Ingram RB 18.8
Michael Carter RB 16.2
Najee Harris RB 15.3
Buffalo Bills DEF 12
Davante Adams WR 11.3
Aaron Rodgers QB 10.48
Tyler Bass K 9
Corey Davis WR 8.8
T.J. Hockenson TE 0

因为那是最上面的2 RB, 1 QB, 2 WR, 1 TE, 1 K, 1 DEF2 FLEX

我已经尝试了以下代码,这让我很接近:

all_points.groupby('Position')['Score'].nlargest(2)

Position    
DEF       0     12.00
K         5      9.00
QB        1     10.48
          14     1.68
RB        8     24.90
          2     18.80
TE        7      0.00
WR        15    11.30
          11     8.80
Name: Score, dtype: float64

但是,这并不能说明FLEX“位置”

我也可以循环遍历数据框并手动执行此操作,但这似乎非常密集。

我怎样才能达到预期的效果?

【问题讨论】:

    标签: python pandas pandas-groupby aggregate


    【解决方案1】:

    创建一个自定义函数,根据您的要求为每个组选择多个玩家,并将此索引保持为idx_best。然后排除所有已经选择的玩家并选择 FLEX 其他玩家为idx_flex。最后提取这两个索引的并集。

    FLEX = requirements_dictionary['FLEX']
    select_players = lambda x: x.nlargest(requirements_dictionary[x.name])
    
    idx_best = df.groupby('Position')['Score'].apply(select_players).index.levels[1]
    idx_flex = df.loc[df.index.difference(idx_best), 'Score'].nlargest(FLEX).index
    
    out = df.loc[idx_best.union(idx_flex)].sort_values('Score', ascending=False)
    

    输出:

    >>> out
                 Player Position  Score
    8   Darrel Williams       RB  24.90
    2       Mark Ingram       RB  18.80
    3    Michael Carter       RB  16.20
    4      Najee Harris       RB  15.30
    0     Buffalo Bills      DEF  12.00
    15    Davante Adams       WR  11.30
    1     Aaron Rodgers       QB  10.48
    5        Tyler Bass        K   9.00
    11      Corey Davis       WR   8.80
    7    T.J. Hockenson       TE   0.00
    

    【讨论】:

    • 感谢您的建议——我没有考虑过尝试使用 index.levels 烘焙解决方案。但是,这不会产生问题中发布的预期解决方案。
    • 唯一的区别是我有 2 个 QB,因为您的输入数据框中有 2 个 QB。所以我不明白为什么你的结果中只有一个。如何排除马特瑞恩?
    • requirements_dictionary 指定最终数据帧中所需的每个位置的数量,困难在于FLEX 的位置可能是众多位置之一。这就是我发布这个具有挑战性的问题的原因。
    • @wundermahn。请检查我的新输出。看起来如你所愿,对吧?
    • 为什么 flex 在你的代码中很重要? flex 不在数据集中
    【解决方案2】:

    使用需求字典获取等于某个位置的行,然后按分数排序并获取与该位置的字典值相等的头部。 Flex 在 RB、WR、TE 中排名前 2。我连接 flex 结果。我的解决方案更直观、更合乎逻辑的理解

    txt="""Player,Position,Score
    Darrel Williams,RB,24.9
    Mark Ingram,RB,18.8
    Michael Carter,RB,16.2
    Najee Harris,RB,15.3
    Buffalo Bills,DEF,12
    Davante Adams,WR,11.3
    Aaron Rodgers,QB,10.48
    Tyler Bass,K,9
    Corey Davis,WR,8.8
    T.J. Hockenson,TE,0"""
    
    df = pd.read_csv(io.StringIO(txt),sep=',')
    requirements_dictionary = {'QB': 1, 'RB': 2, 'WR': 2, 'TE': 1, 'K': 1, 'DEF': 1, 'FLEX': 2}
    #print(df)
    df_top_rows = pd.DataFrame()
    for position in requirements_dictionary.keys():
        df_top_rows = df_top_rows.append(df[df['Position'] == position].sort_values(by='Score', ascending=False).head(requirements_dictionary[position]))
    print(df_top_rows)
    
    position='FLEX'
    df_flex_rows = df_top_rows.append(df[df['Position'].isin(['RB','WR','TE'])].sort_values(by='Score', ascending=False).head(requirements_dictionary[position]))
    
    #print(df_flex_rows)
    df_result=pd.concat([df_top_rows,df_flex_rows],axis=0)
    df_result.drop_duplicates(inplace=True)
    print(df_result)
    

    输出

           Player Position  Score
    6    Aaron Rodgers       QB  10.48
    0  Darrel Williams       RB  24.90
    1      Mark Ingram       RB  18.80
    5    Davante Adams       WR  11.30
    8      Corey Davis       WR   8.80
    9   T.J. Hockenson       TE   0.00
    7       Tyler Bass        K   9.00
    4    Buffalo Bills      DEF  12.00​
    

    【讨论】:

      猜你喜欢
      • 2021-08-09
      • 2015-06-08
      • 1970-01-01
      • 2010-10-14
      • 1970-01-01
      • 2021-07-11
      • 2021-11-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多