Python 同时计算两列上的展开平均值
我有一张由两名选手组成的比赛桌:Python 同时计算两列上的展开平均值,python,pandas,mean,Python,Pandas,Mean,我有一张由两名选手组成的比赛桌: 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
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
我想应用扩展平均值,这样每个玩家的ptsA
和ptsB
都会被计入净结果中(并且不会被留下)。最终输出应更加清楚:
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')
,然后我画了一个空白,如何正确地连接这两个结果
也许熊猫提供了一个内置的或者你有一个解决方案
@用稍微不同的数据编辑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
。(请参考下面的固定解决方案)
一种方法是先找出所有玩家的名字:
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
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
编辑:固定解决方案: 对于两个以上的名称,这就是如何为展开平均值构建公式的方法:
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
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
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)。根据您的第一个答案,我提出了类似的解决方案(与您的固定解决方案类似),并且可能更容易理解:mask=st.scA*(st.plA==name)+st.scB*(st.plB==name)st['mean'+name]=pd.expansing_-mean(mask[mask>0])。无论如何,我不太愿意接受你的答案,因为输出格式不是特别方便。有了更多的球员,桌子就变宽了。理想情况下,应该只有两个新的列
mean_plA
,mean_plB
,其值取决于两个实际玩家是谁。毕竟,我会继续接受答案,因为多亏了你的帮助,我成功地找到了满意的答案;)@嘿,很高兴听到这个消息,你应该用你的简化解决方案发布另一个答案,以后作为参考总是很好的。。。