2014-01-26 54 views
1

我有2名球員的互相競爭的一個表:計算擴大意味着對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')然後林繪圖一個空白的如何正確地加入這兩個結果。

也許大熊貓提供了一個內置的或者你有一個解決方案嗎?

@EDIT Saullo卡斯特羅的略有不同的數據

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一路。

回答

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 

編輯:固定的解決方案:

對於兩個以上的名字,這是如何構建的擴大是指式:

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))) 

,導致

+1

嗨,這可能是一些很好的提示,但是如果任何玩家的名字被替換爲新玩家名稱,它就會失敗。結果將是完全錯誤的。看到我更新的帖子。 – nutship

+0

@shipship很好觀察...我試圖找出另一個解決方案 –

+1

再次感謝您付出努力更新(+1 ofc)。根據你的第一個答案,我想出了類似的,(對你的固定解決方案),或許更容易理解,解決方案名稱爲: mask = st.scA *(st.plA == name)+ st。 scB *(st.plB == name) st ['mean'+ name] = pd.expanding_mean(mask [mask> 0])''。無論如何,我很猶豫接受你的答案,因爲輸出格式不是特別方便。隨着更多球員,桌子變得寬廣。理想情況下,應該只有兩個新列「mean_plA」,「mean_plB」,值依賴於兩個實際玩家是誰。 – nutship