我想將滾動函數應用於由兩列重複日期條目分組的數據框。具體來說,將「freq」和「window」作爲日期時間值,而不是簡單地整數。將滾動函數應用於groupby多列
原則上,我試圖結合How to apply rolling functions in a group by object in pandas和pandas rolling sum of last five minutes中的方法。
輸入
下面是數據的樣本,一個ID = 33,雖然我們預計幾個ID的。
X = [{'date': '2017-02-05', 'id': 33, 'item': 'A', 'points': 20},
{'date': '2017-02-05', 'id': 33, 'item': 'B', 'points': 10},
{'date': '2017-02-06', 'id': 33, 'item': 'B', 'points': 10},
{'date': '2017-02-11', 'id': 33, 'item': 'A', 'points': 1},
{'date': '2017-02-11', 'id': 33, 'item': 'A', 'points': 1},
{'date': '2017-02-11', 'id': 33, 'item': 'A', 'points': 1},
{'date': '2017-02-13', 'id': 33, 'item': 'A', 'points': 4}]
# df = pd.DataFrame(X) and reindex df to pd.to_datetime(df['date'])
df
id item points
date
2017-02-05 33 A 20
2017-02-05 33 B 10
2017-02-06 33 B 10
2017-02-11 33 A 1
2017-02-11 33 A 1
2017-02-11 33 A 1
2017-02-13 33 A 4
目標
樣品每個的 'id' 每2天(FREQ = '2D')和在所述前三天返回總點數的總和爲每個項目(窗口= '3D' ),結束日期包容
所需的輸出
id A B
date
2017-02-05 33 20 10
2017-02-07 33 20 30
2017-02-09 33 0 10
2017-02-11 33 3 0
2017-02-13 33 7 0
例如在包含權利的結束日期2017-02-13中,我們會將2017-02-11的3天期間抽樣爲2017-02-13。在此期間,ID = 33具有A點的等於1 + 1 + 1 + 4 = 7
嘗試
GROUPBY的與pd.rolling_sum試圖如下沒有工作的總和,由於反覆日期
df.groupby(['id', 'item'])['points'].apply(pd.rolling_sum, freq='4D', window=3)
ValueError: cannot reindex from a duplicate axis
還請注意,從文檔http://pandas.pydata.org/pandas-docs/version/0.17.0/generated/pandas.rolling_apply.html「窗口」是表示大小採樣週期一個int,而不是幾天採樣數。
我們也可以嘗試重新採樣並使用最後,然而3天所需的外觀,背部也不會被使用
df.groupby(['id', 'item'])['points'].resample('2D', label='right', closed='right').\
apply(lambda x: x.last('3D').sum())
id item date
33 A 2017-02-05 20
2017-02-07 0
2017-02-09 0
2017-02-11 3
2017-02-13 4
B 2017-02-05 10
2017-02-07 10
當然,設立了唯一的ID號循環,選擇df_id = df [df ['id'] == ID],並且對這些時間段進行求和可以工作,但是計算量很大,並且不會利用groupby的良好矢量化。
感謝@jezrael對於好的建議,到目前爲止
注意
熊貓版= 0.20.1
我有點困惑,爲什麼在滾動的文檔()這裏:https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.rolling.html 建議「窗口」參數可以在一個int或偏移量,但在嘗試df.rolling(window ='3D',...)我得到raise ValueError("window must be an integer")
看來,上述文件是不符合最新C從./core/window開始滾動窗口。潘岳: https://github.com/pandas-dev/pandas/blob/master/pandas/core/window.py
elif not is_integer(self.window):
raise ValueError("window must be an integer")
感謝解釋。有關使用滾動方法訪問日期時間值的任何提示(例如,給定窗口中最近一次非零輸入的時間)?目前,似乎只有浮點數X可以在像d.rolling('3D')這樣的調用中訪問。apply(lambda X:func(X))。resample('2D') – Quetzalcoatl
聽起來像它應該是一個單獨的問題。提示將在屏蔽零作爲「np.nan」後使用'pd.Series.first_valid_index'或'pd.Series.last_valid_index'。你也可以在'numpy'中做一些其他的技巧。 – piRSquared