2017-03-06 16 views
2

の前の日に平均値を加重移動:すべてのグループ(1、2)では新しさは、私は次のdf持っパンダ

index = pd.to_datetime(['2017-03-01', '2017-03-01', '2017-02-15', '2017-02-01', 
     '2017-01-20', '2017-01-20', '2017-01-20', '2017-01-02', 
     '2016-12-04', '2016-12-04', '2016-12-04', '2016-11-16']) 

df = pd.DataFrame(data = {'val': [8, 1, 5, 2, 3 , 5, 9, 14, 13, 2, 1, 12], 
       'group': ['one', 'two', 'one', 'one', 'two', 'two', 'one', 'two', 
       'two', 'one', 'one', 'two']}, 
       index=index) 

df = df.sort_index() 

      group val 
2016-11-16 two 12 
2016-12-04 two 13 
2016-12-04 one 2 
2016-12-04 one 1 
2017-01-02 two 14 
2017-01-20 two 3 
2017-01-20 two 5 
2017-01-20 one 9 
2017-02-01 one 2 
2017-02-15 one 5 
2017-03-01 one 8 
2017-03-01 two 1 

を私は、以前のvalの新し加重平均したいと思います。グループ1を見て例えばので:例えば

  group val 
2016-12-04 one 2 
2016-12-04 one 1 
2017-01-20 one 9 
2017-02-01 one 2 
2017-02-15 one 5 
2017-03-01 one 8 

、日付2017-02-15については、私は、この日のための値として近い日付の最新性加重バージョン(高い重みを持つ新しい列を計算したいです過去の値の[2,9,1,2]である。 1つのグループ内で複数の日付を持つ可能性があり、同じ重みを取得する必要があることに注意してください。

私はパンダの指数関数的に重み付けされた関数がこれには良いと思った。あるグループ内の日付が同じであるとわかりました。後で単純なshift()を適用できるように、最初にそれらの値の平均値を取ることになります。私は、次のことを試してみました:

df = df.reset_index().set_index(['index', 'group']).groupby(
     level=[0,1]).mean().reset_index().set_index('index') 

私は

df = df.groupby('group')['val'].expanding().mean().groupby(level=0).shift() 

ような何かをして、その後、日付とグループの元と合併する可能性が新し重み付けに興味がないならば。 しかし、私は何か足りないのですpandas.ewmaの使用作るしようとすると:私はグループを反復処理することができます

df.groupby('group')['val'].ewm(span=27).groupby(level=0).shift() 

grouped = df.groupby('group')['val'] 
for key, group in grouped: 
    print pd.ewma(group, span=27).shift() 

index 
2016-12-04   NaN 
2017-01-20 1.500000 
2017-02-01 5.388889 
2017-02-15 4.174589 
2017-03-01 4.404414 
Name: val, dtype: float64 
index 
2016-11-16   NaN 
2016-12-04 12.000000 
2017-01-02 12.518519 
2017-01-20 13.049360 
2017-03-01 10.529680 

をして、何とか元のグループと日付で合併をdfしかし、これはあまりにも複雑に思えます。これを行うより良い方法はありますか?

答えて

1

シュテファンaswerに基づき、ここで作業バージョンです:

def rwma(group): 
    # perform the ewma 
    kwargs = dict(ignore_na=False, span=27, min_periods=0, adjust=True) 
    result = group.resample('1D').mean().ewm(**kwargs).mean().shift() 
    result = result[group.index].reset_index() 

    # rename the result column so that the merge goes smoothly 
    result.rename(columns={result.columns[-1]: 'rwma'}, inplace=True) 
    return result 

recency = df.groupby('group')['val'].apply(rwma) 
print(recency) 

出力:

    index  rwma 
group       
one 0 2016-12-04  NaN 
     1 2016-12-04  NaN 
     2 2017-01-20 1.500000 
     3 2017-02-01 8.776518 
     4 2017-02-15 4.016278 
     5 2017-03-01 4.670166 
two 0 2016-11-16  NaN 
     1 2016-12-04 12.000000 
     2 2017-01-02 12.791492 
     3 2017-01-20 13.844843 
     4 2017-01-20 13.844843 
     5 2017-03-01 6.284914 
+0

でなければならないので混乱するかもしれません本当ですか?お手伝いしましたか?一口。 –

2

リーフウェイト移動平均を実行して、グループをループして再マージする必要がない場合は、applyを使用できます。

def rwma(group): 
    # perform the ewma 
    kwargs = dict(ignore_na=False, span=27, min_periods=0, adjust=True) 
    result = group.ewm(**kwargs).mean().shift().reset_index() 

    # rename the result column so that the merge goes smoothly 
    result.rename(columns={result.columns[-1]: 'rwma'}, inplace=True) 
    return result 

recency = df.groupby('group')['val'].apply(rwma) 

テストコード:

import pandas as pd 

df = pd.DataFrame(data={ 
    'val': [8, 1, 5, 2, 3, 5, 9, 14, 13, 2, 1, 12], 
    'group': ['one', 'two', 'one', 'one', 'two', 'two', 
       'one', 'two', 'two', 'one', 'one', 'two']}, 
    index=pd.to_datetime([ 
     '2017-03-01', '2017-03-01', '2017-02-15', '2017-02-01', 
     '2017-01-20', '2017-01-20', '2017-01-20', '2017-01-02', 
     '2016-12-04', '2016-12-04', '2016-12-04', '2016-11-16']) 
    ).sort_index() 

recency = df.groupby('group')['val'].apply(rwma) 
print(recency) 

結果:

   index  rwma 
group       
one 0 2016-12-04  NaN 
     1 2016-12-04 2.000000 
     2 2017-01-20 1.481481 
     3 2017-02-01 4.175503 
     4 2017-02-15 3.569762 
     5 2017-03-01 3.899694 
two 0 2016-11-16  NaN 
     1 2016-12-04 12.000000 
     2 2017-01-02 12.518519 
     3 2017-01-20 13.049360 
     4 2017-01-20 10.251243 
     5 2017-03-01 9.039866 
+0

ありがとうスティーブン。この問題は、グループ1では12-04の値を知ることができません。なぜなら前日のvalの計算しかできないからです。私はそれを修正し、下記の作業バージョンを掲載しました。あなたの答えは間違いなく私を助けました! – jens0r

+0

タイトルは「パンダの前の日の最近の加重移動平均」 – jens0r

関連する問題