【问题标题】:Calculating expanding mean on 2 columns simultaneously同时计算2列的扩展平均值
【发布时间】:2014-02-17 03:26:34
【问题描述】:

我有一张由 2 名玩家组成的桌子:

    date         plA    plB    ptsA ptsB
0   01/01/2013  Jeff    Tom     78  72
1   15/01/2013  Jeff    Tom     52  67
2   01/02/2013  Tom     Jeff    91  93
3   15/02/2013  Jeff    Tom     83  87
4   01/03/2013  Tom     Jeff    65  76

我想应用扩展均值,这样每个玩家的ptsAptsB 都被计入(而不是离开)净结果。最终输出应该更清楚:

    date         plA    plB    ptsA ptsB   meanA  meanB 
0   01/01/2013  Jeff    Tom     78  72      78     72      # init mean
1   15/01/2013  Jeff    Tom     52  67      65     69.5 
2   01/02/2013  Tom     Jeff    91  93      74.3   76.6    # Tom: (72+67+91)/3, Jeff: (78+52+93)/3
3   15/02/2013  Jeff    Tom     83  87      76.5   79.25   # Jeff: (78+52+93+83)/4, Tom: (72+67+91+87)/4
4   01/03/2013  Tom     Jeff    65  76      76.4   76.4    # Tom: (72+67+91+87+65)/5, Jeff: (78+52+93+83+76)/5

现在,我开始按plA 对数据进行分组,如下所示:

by_A = players.sort(columns='date').groupby('plA')
players['meanA'] = by_A['ptsA'].apply(pd.expanding_mean)
players['meanB'] = by_A['ptsB'].apply(pd.expanding_mean)

显然,我需要做同样的事情,groupby('plB') 然后我画了一个空白,如何正确连接这两个结果。

也许 pandas 提供了内置的,或者您有解决方案?

@EDIT Saullo Castro 的数据略有不同的解决方案

    date    studentA    studentB    scoreA  scoreB  meanJeff    meanTom     meanMaggie
0   2013-01-01  Jeff    Tom     78  72             78.000000    72.000000   0.000000
1   2013-01-15  Jeff    Maggie  52  67             65.000000    36.000000   33.500000
2   2013-02-01  Tom     Jeff    91  93             74.333333    54.333333   22.333333
3   2013-02-15  Jeff    Tom     83  87             76.500000    62.500000   16.750000
4   2013-03-01  Tom     Jeff    65  76             76.400000    63.000000   13.400000

Maggie 的意思应该一直保持67

【问题讨论】:

    标签: python pandas mean


    【解决方案1】:

    (请参考下面的固定解决方案)

    一种方法是先找出所有玩家的名字:

    names = pd.concat((df.plA, df.plB)).unique()
    

    然后为每个玩家创建一个具有扩展平均值的新列:

    for name in names:
        df['mean'+name] = pd.expanding_mean(df.ptsA*(df.plA==name) + df.ptsB*(df.plB==name))
    

    导致:

                      date   plA   plB  ptsA  ptsB   meanJeff    meanTom
    0  2013-01-01 00:00:00  Jeff   Tom    78    72  78.000000  72.000000
    1           15/01/2013  Jeff   Tom    52    67  65.000000  69.500000
    2  2013-01-02 00:00:00   Tom  Jeff    91    93  74.333333  76.666667
    3           15/02/2013  Jeff   Tom    83    87  76.500000  79.250000
    4  2013-01-03 00:00:00   Tom  Jeff    65    76  76.400000  76.400000
    

    编辑:固定解决方案:

    对于两个以上的名称,您可以通过以下方式构建扩展均值公式:

    df = pd.read_excel('stack.xlsx', 'tabelle1')
    names = pd.concat((df.plA, df.plB)).unique()
    for name in names:
        nA = df.plA==name
        nB = df.plB==name
        df['mean'+name] = np.cumsum(df.ptsA*nA + df.ptsB*nB)/np.maximum(1.,
                                         np.cumsum(1.*np.logical_or(nA, nB)))
    

    导致:

    date   plA     plB  ptsA  ptsB   meanJeff    meanTom  meanMaggie
    0 2013-01-01 00:00:00  Jeff     Tom    78    72  78.000000  72.000000     0
    1 2013-01-15 00:00:00  Jeff  Maggie    52    67  65.000000  72.000000    67
    2 2013-02-01 00:00:00   Tom    Jeff    91    93  74.333333  81.500000    67
    3 2013-02-15 00:00:00  Jeff     Tom    83    87  76.500000  83.333333    67
    4 2013-03-01 00:00:00   Tom    Jeff    65    76  76.400000  78.750000    67
    

    【讨论】:

    • 嗨,这可能是一个很好的提示,但如果任何球员的名字被替换为新名字,它就会失败。结果将是完全错误的。查看我更新的帖子。
    • @nutship 观察良好...我正在尝试找出另一种解决方案
    • 再次感谢您努力更新(+1 ofc)。根据您的第一个答案,我提出了类似的(与您的固定解决方案相似的)并且可能更容易理解的解决方案for name in names: mask = st.scA*(st.plA==name) + st.scB*(st.plB==name) st['mean' + name] = pd.expanding_mean(mask[mask > 0])。无论如何,我很犹豫是否接受您的回答,因为输出格式不是特别方便。随着更多的玩家,桌子变得更宽。理想情况下,应该只有两个新列 mean_plAmean_plB,其值取决于 2 个实际玩家是谁。
    • 毕竟我会继续接受答案,因为在你的帮助下,我设法把它弄到了令人满意的程度;)
    • @nutship 嘿,很高兴听到这个消息,你应该用你的简化解决方案发布另一个答案,以后作为参考总是好的......
    猜你喜欢
    • 2021-08-09
    • 1970-01-01
    • 2022-12-02
    • 1970-01-01
    • 2021-04-09
    • 1970-01-01
    • 2020-05-20
    • 2012-07-12
    • 1970-01-01
    相关资源
    最近更新 更多