【问题标题】:More efficient way to write this for loop?更有效的方式来编写这个 for 循环?
【发布时间】:2021-11-18 17:03:47
【问题描述】:
import pandas as pd

sim = [['Matthew Stafford', 15, 13, 12], ['Dalvin Cook', 18, 16, 17], ['Daniel Jones', 17, 17, 15], ['Joe Mixon', 16, 15, 15]]
col = ['Player', 1 , 2, 3]
NFL_Sim = pd.DataFrame(sim, columns=col)
list = [['Matthew Stafford', 'Dalvin Cook'], ['Daniel Jones', 'Joe Mixon']]
col = ['QB', 'RB']
output_lines = pd.DataFrame(list, columns=col)

for x in range(1, 4):
    output_lines[x] = output_lines.QB.map(NFL_Sim.set_index('Player')[x].to_dict()) + output_lines.RB.map(NFL_Sim.set_index('Player')[x].to_dict())

print(output_lines)

                 QB           RB   1   2   3
0  Matthew Stafford  Dalvin Cook  33  29  29
1      Daniel Jones    Joe Mixon  33  32  30

所需的输出是正确的,但是随着我的扩展,我在 NFL_Sim 数据框中有数千列,这使得映射非常慢。有没有更有效的方法来编写这个 for 循环?还是先将 output_lines 转换为列表?我真的不确定什么是最好的。

【问题讨论】:

  • 请发布预期的输出数据框
  • 抱歉,我已经发布了。

标签: python pandas list for-loop


【解决方案1】:

使用系列创建映射:(QB 和 RB 的配对在 output_lines 中处理,我们希望使用索引位置连接到 NFL_Sim)

mapping = output_lines.T.stack()
mapping = pd.Series(mapping.index.droplevel(0), mapping)

获取每个位置的总和:

mapping = (NFL_Sim.assign(positions = lambda df: df.Player.map(mapping))
           # we do not need the Player column anymore,
           # since we have our mapping
                 .select_dtypes('number')
                 .groupby('positions')
                 .sum()
           )

将映射重新连接回 output_lines

output_lines.join(mapping)

                 QB           RB   1   2   3
0  Matthew Stafford  Dalvin Cook  33  29  29
1      Daniel Jones    Joe Mixon  33  32  30

【讨论】:

    【解决方案2】:

    首先,我建议您在创建时设置一次NFL_Sim 的索引。这样您就不必在循环内执行两次。

    其次,如果您有一个四分卫列表和一个跑卫列表,我建议您创建两个矩阵:一个用于四分卫,一个用于跑卫。然后你可以把这两个加在一起。

    import pandas as pd
    
    sim = [['Matthew Stafford', 15, 13, 12], ['Dalvin Cook', 18, 16, 17], ['Daniel Jones', 17, 17, 15], ['Joe Mixon', 16, 15, 15]]
    col = ['Player', 1 , 2, 3]
    NFL_Sim = pd.DataFrame(sim, columns=col).set_index('Player')
    qbs = ['Matthew Stafford', 'Daniel Jones']
    rbs = ['Dalvin Cook', 'Joe Mixon']
    
    qb_scores = NFL_Sim.loc[qbs, :]
    rb_scores = NFL_Sim.loc[rbs, :]
    # We need to reset the index because otherwise the addition
    # of qb_scores and rb_scores will not be compatible; they have
    # different indexes
    output = qb_scores.reset_index(drop=True) + rb_scores.reset_index(drop=True)
    output = output.assign(QB=qbs, RB=rbs)
    

    【讨论】:

    • 我尝试运行这个确切的代码并得到“KeyError:“[Index(['Matthew Stafford', 'Dalvin Cook'], dtype='object')] 在 [columns] "
    • 我认为 NFL_sim[qbs] 发生了这种情况,因为 Pandas DataFrames 中的默认索引是针对列的。应该是NFL_sim.loc[qbs, :]
    • 我还看到 qbsrbs 列表混淆了。 qbs 应该是 Matthew Stafford 和 Daniel Jones。 rbs 应该是Dalvin Cook 和Joe Mixon。我也更正了这一点。
    【解决方案3】:

    melt 是一种更加动态的方式:

    >>> x = output_lines.melt(value_name='Player', ignore_index=False).merge(NFL_Sim, on='Player')
    >>> output_lines = output_lines.join(x.loc[[*x.index[::2], *x.index[1::2]]].groupby(x.index // 2).sum())
    >>> output_lines
                     RB           QB   1   2   3
    0  Matthew Stafford  Dalvin Cook  33  29  29
    1      Daniel Jones    Joe Mixon  33  32  30
    >>> 
    

    【讨论】:

    • 哇,我希望我对熊猫的了解不仅仅是基础知识......
    • @Jab 哈哈!是的,这很复杂:)
    • 我只知道危险。]
    • @Jab 哈哈 :P!!!
    • 检查您描述中的电子邮件收件箱。请
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-06
    • 1970-01-01
    相关资源
    最近更新 更多