[英]Create rolling windows in pandas based on window size specified in another column
[英]Pandas rolling window with custom look back length based on column sum
給定一個熊貓數據框,其中有以日期為索引的“ atbats”和“ hits”兩列,是否可以獲得最新的歷史擊球平均值(每個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次/擊球。
在第三天,我們將回顧過去的三天,得出(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個,因此會大大增加數據框的大小和要計算的窗口總數。
使用迭代來實現您所需要的。 見下文:
原始數據框:
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
可能可以進行優化,但我認為它將對您有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.