2つの列でグループ化されたデータフレームに繰り返し機能を適用したいと思います。具体的には、単純にintではなくdatetime値として "freq"と "window"の両方を使用します。複数の列でグループにローリング機能を適用する
原則として、私はHow to apply rolling functions in a group by object in pandasとpandas rolling sum of last five minutesのメソッドを組み合わせようとしています。我々はいくつかのIDを期待するが、ここで入力
は、1つのID = 33で、データのサンプルです。
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')と過去3日間(ウィンドウ= '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から2017-02-13までの3日間をサンプリングします。この期間では、ID = 33が試み
pd.rolling_sumとGROUPBYの試み次のようには機能しなかった1 + 1 + 1 + 4 = 7
に等しいポイントの合計を持っていました、繰り返し日付
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、ないサンプリングする日数であることに注意してください。 またdf_idを選択し、一意のIDのIDの上にループを設定し、しかし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
を使用していないよう、最後にリサンプリングして使ってみてくださいすることができます= df [df ['id'] == ID]となり、期間の合計は機能しますが、計算量が多く、groupbyの素敵なベクトル化を利用しません。ここ
おかげで良い提案を@jezraelするこれまで
ノート
パンダバージョン= 0.20.1
私は(ローリング上の理由ドキュメントへのわずか混乱しています) :https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.rolling.html は、 "window"パラメータがintまたはoffsetにあるが、df.rolling(window = '3D'、...)を試みていることを示唆しているraise ValueError("window must be an integer")
上記のドキュメントは、最新のc ./core/windowからローリングのウィンドウのためのode。PY: 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")
感謝。ローリング方法で日付/時刻値にアクセスする際のヒント(たとえば、特定のウィンドウで最も最近ゼロでないエントリの時間)現時点では、浮動小数点数の配列だけが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