2017-09-14 32 views
0

給定一個包含兩列的「大熊貓」和「命中」的熊貓數據框,以日期爲索引,是否有可能獲得最近的歷史擊球平均數(平均數每個atbat命中)?例如,歷史打擊平均值可能是最少的大於10的平均值。這有點像帶有有條件的回溯期的滾動窗口。例如,給定:基於列總和的自定義回望長度的大熊貓滾動窗口

 date, atbats, hits, 
2017-01-01,  5, 2, 
2017-01-02,  6, 3, 
2017-01-03,  1, 1, 
2017-01-04,  12, 3, 
2017-01-04,  1, 0, 

在第一天,就沒有歷史演出了。在第二天,只有6.因爲兩者都小於10,所以它們可以是NaN或僅爲0.

第三天,我們回頭看看最後兩天,看到5 + 6個平均值(2 + 3)/(5 + 6)= 0.45命中/ atbat。在第三天,我們回顧過去三天,得到(2 + 3 + 1)/(5 + 6 + 1)= 0.5點/每小時。

第四天,我們會回頭看看最後一天,並得到4/16 = 0.25命中/ atbat。由於最後一天有超過10(16),我們不需要再看。

最終的數據幀將如下所示:

 date, atbats, hits, pastAtbats, pastHits, avg, 
2017-01-01,  5, 2,   0,  0, 0, 
2017-01-02,  6, 3,   0,  0, 0, 
2017-01-03,  1, 1,   11,  5, 0.45, 
2017-01-04,  16, 4,   12,  6, 0.50, 
2017-01-04,  1, 0,   16,  4, 0.25, 

這算哪門子的大熊貓計算可能的?

我能想到的唯一解決方案就是純蠻力 - 在每行中用atbats分隔命中,每一行復制x次,其中x = atbats,然後做一個10的滾動窗口。但是在我的數據框中,「atbats」的平均值大約爲每天80次,所以它將大大增加數據幀的大小和計算窗口的總數。

回答

0

使用iterrows來實現你所需要的。請看下圖:

原始數據幀:

index atbats hits 
1  5  2 
2  6  3 
3  1  1 
4  16  4 
4  1  0 
5  1  0 
6  14  2 
7  5  1 

代碼:

data = [] 
last = [0,0] 
past_atbats = 0 
past_hits = 0 
for i, row in df.iterrows(): 
    if(last[0] >= 10): 
     data.append(last.copy()) 
    else: 
     data.append([0,0]) 

    if(row['atbats'] >= 10): 
     last[0] = row['atbats'] 
     last[1] = row['hits'] 
    else: 
     last[0] += row['atbats'] 
     last[1] += row['hits'] 

df_past = pd.DataFrame(data=data,index=df.index,columns=['past_atbats','past_hits']) 
df = df.merge(df_past,left_index=True,right_index=True) 
df['avg'] = df['past_hits'].divide(df['past_atbats']) 

導致:

index atbats hits past_atbats past_hits  avg 
1  5  2   0   0  NaN 
2  6  3   0   0  NaN 
3  1  1   11   5 0.454545 
4  16  4   12   6 0.500000 
4  16  4   16   4 0.250000 
4  1  0   12   6 0.500000 
4  1  0   16   4 0.250000 
5  1  0   17   4 0.235294 
6  14  2   18   4 0.222222 
7  5  1   14   2 0.142857 

優化大概可以這樣做,但我認爲這將幫助你。

+0

我希望有更多的性能......使用iterrows實際上只是手動迭代每一行。 – Albeit