nのシフトを伴うPythonPandas cumsum

Oct 01 2020

nのシフトを使用serie.cumsum()して、を実行する効率的な方法(forループを回避する)があるかどうかを知りたいです。

serie.cumsum()逆数のように見えるのと同じように、次の逆数をserie.diff(1)探していますdiff(n)(適切な逆数には初期値が必要ですが、簡単にするためにここでは無視します)。cumsum_shift

forループでより明示的に実装する(これは避けたい):

def cumsum_shift(s, shift = 1, init_values = [0]):
    s_cumsum = pd.Series(np.zeros(len(s)))
    for i in range(shift):
        s_cumsum.iloc[i] = init_values[i]
    for i in range(shift,len(s)):
        s_cumsum.iloc[i] = s_cumsum.iloc[i-shift] + s.iloc[i]
    return s_cumsum

このコードshift = 1はs.cumsum()pandasメソッドとまったく同じですが、もちろんpandasメソッドはCコードで実行するため(おそらく)、はるかに高速です(もちろん、常にs.cumsum()pandasメソッドを使用し、forを使用して自分で実装しないでください)。ループ)。

私の質問は、パンダメソッドでforループを回避する方法は何でしょうcumsum_shiftか?

編集1

入力と出力の例を追加する

あなたがそれを呼び出す場合:

s = pd.Series([1,10,100,2,20,200,5,50,500])
s.diff(3)
out[26] 0      NaN
        1      NaN
        2      NaN
        3      1.0
        4     10.0
        5    100.0
        6      3.0
        7     30.0
        8    300.0
        dtype: float64

この入力により、の出力cumsum_shift(s.diff(3), shift = 3, init_values = [1,2,3])は再び元のシリーズになりsます。3のシフトに注意してください。これは、cumsum()たとえばs.diff(3).cumsum()、元の値を復元しませんs。

cumsum_shift(s.diff(3), shift = 3, init_values= [1,10,100])
out[27]
0      1.0
1     10.0
2    100.0
3      2.0
4     20.0
5    200.0
6      5.0
7     50.0
8    500.0
dtype: float64

ただし、初期値は大した問題ではなく、一定の差は問題ではないことを強調しておきます。forループを使用せずにシフトされた差分セリエの累積を実行する方法を知りたい

adiff()を実行してからaを実行するとcumsum()、元の値が初期値に戻るのと同じ方法です。

s = pd.Series([1,10,100,2,20,200,5,50,500])
s.diff().cumsum()
out[28]
0      NaN
1      9.0
2     99.0
3      1.0
4     19.0
5    199.0
6      4.0
7     49.0
8    499.0
dtype: float64

s.diff(n).cumsum(n)そのようなことを行うための巧妙な方法が、一定の初期値まで正しいものを返すかどうかを知りたいと思います。

編集2-移動平均を逆にする

「シフトされたcumsum」のアプリケーションを考えると、SOで、関数を使用して回答した移動平均を逆にする方法についてのこの別の質問を見つけました。これにより、cumsum_shiftここで求めていることがより明確になると思います。

回答

1 Elif Oct 01 2020 at 21:34

次のように、パンダメソッドrolling.sum()を使用できます。

s.rolling(shift).sum()

ただし、シフトするまでNaN値を元のdfで埋めることができます。