2017-03-24 10 views
2

、私は新しい列を作成しようとしています。このはパンダの列をシフトし、次の3つの値の平均を取る(post_shift)私はデータフレームを持って

  Open High Low Close Volume 
Date           
2007-03-22 2.65 2.95 2.64 2.86 176389 
2007-03-23 2.87 2.87 2.78 2.78 63316 
2007-03-26 2.83 2.83 2.51 2.52 54051 
2007-03-27 2.61 3.29 2.60 3.28 589443 
2007-03-28 3.65 4.10 3.60 3.80 1114659 
2007-03-29 3.91 3.91 3.33 3.57 360501 
2007-03-30 3.70 3.88 3.66 3.71 185787 

のように見える最初にそのdf Open列を3行シフトし(df.Open.shift(-3))、それ自身と次の2つの値の平均値をとります。

は、したがって、たとえば上記のデータフレームのOpen列は-3行をシフトし、このようなものになり、次のようになります。私は、その後の繰り返しを介して次の3つの値(自身を含む)の前方平均を取りたい

Date 
2007-03-22 2.610 
2007-03-23 3.650 
2007-03-26 3.910 
2007-03-27 3.700 
2007-03-28 3.710 
2007-03-29 3.710 
2007-03-30 3.500 

を。 したがって、最初の反復は、次の値である2.610(最初の値)+ 3.650 + 3.910を3で割ったものになります。 次に、次の値3.650(最初の値)を取ります。値の列を作成する。

は、最初に私はのような何か試してみました:

df['Avg'] =df.Open.shift(-3).iloc[0:3].mean() 

をしかし、これはOpen.shift

のすべての値を反復処理しないこの次のループは動作するようですが、非常に遅いです、そして私がいましたパンダのforループを使うのは悪い習慣だと言った。

for i in range(0, len(df.Open)): 
    df['Avg'][i] =df.Open.shift(-3).iloc[i:i+4].mean() 

私は

df.Open.shift(-3).apply(loc[0:4].mean()) 
df.Open.shift(-3).apply(lambda x: x[0:4].mean()) 

を適用し使用する方法の思考しようとしたが、これらは私がエレガントな方法を考えることはできませんようになど

TypeError: 'float' object is not subscriptableなどのエラーを与えているようですこれは

ありがとうございます。

答えて

3

pandas rolling_meanを使用できます。逆方向ウィンドウを使用するので、最初の2行は2.61(値自体)と3.13(行0と行1の平均)になります。これを処理するには、shift(-2)を使用して2行分の値をシフトできます。

pd.rolling_mean(df, window=3, min_periods=1).shift(-2) 

出力:

  open 
date  
2007-03-22 3.390000 
2007-03-23 3.753333 
2007-03-26 3.773333 
2007-03-27 3.706667 
2007-03-28 3.640000 
2007-03-29 NaN 
2007-03-30 NaN 
+0

ああでそれをラップすることができます。はいわかりました。最初はちょっと混乱しましたが、うまくいっているようです(私はそれを試してみた後に)最高の答えを与える前に何か別の答えがあるのを待ってみるつもりです。ありがとうございました。 – Moondra

+0

@moondra今は飛行機に乗っています。しかし、これは完璧なパンダの答えです。 – piRSquared

+0

構文的には、代わりにローリング方式を使うのが好きです。 df.open.rolling(3、min_periods = 1).mean()。shift(-2) – piRSquared

1

numpyソリューション
約束しNOTEとして

:HUGE CAVEAT
これは、高度な技術であり、任意の初心者にはお勧めしません! !
これを使用すると、実際にあなたのプードルをうっかり剃るかもしれません。注意してください!

as_strided

from numpy.lib.stride_tricks import as_strided 
import numpy as np 
import pandas as pd 

# I didn't have your full data for all dates 
# so I created my own array 
# You should be able to just do 
# o = df.Open.values 
o = np.array([2.65, 2.87, 2.83, 2.61, 3.65, 3.91, 3.70, 3.71, 3.71, 3.50]) 

# because we shift 3 rows, I trim with 3: 
# because it'll be rolling 3 period mean 
# add two np.nan at the end 
# this makes the strides cleaner.. sortof 
# whatever, I wanted to do it 
o = np.append(o[3:], [np.nan] * 2) 

# strides are the size of the chunk of memory 
# allocated to each array element. there will 
# be a stride for each numpy dimension. for 
# a one dimensional array, I only want the first 
s = o.strides[0] 

# it gets fun right here 
as_strided(o, (len(o) - 2, 3), (s, s)) 
#  ^ \___________/ \__/ 
#   |    \  \______ 
# object to stride --- size of array --- \ 
#      to make   memory chunk 
#          to step forward 
#          per dimension 

[[ 2.61 3.65 3.91] 
[ 3.65 3.91 3.7 ] 
[ 3.91 3.7 3.71] 
[ 3.7 3.71 3.71] 
[ 3.71 3.71 3.5 ] 
[ 3.71 3.5 nan] 
[ 3.5 nan nan]] 

今、私たちはただの平均を取ります。すべて一緒に

o = np.array([2.65, 2.87, 2.83, 2.61, 3.65, 3.91, 3.70, 3.71, 3.71, 3.50]) 
o = np.append(o[3:], [np.nan] * 2) 
s = o.strides[0] 
as_strided(o, (len(o) - 2, 3), (s, s)).mean(1) 

array([ 3.39  , 3.75333333, 3.77333333, 3.70666667, 3.64  , 
      nan,   nan]) 

あなたはパンダシリーズ

pd.Series(
    as_strided(o, (len(o) - 2, 3), (s, s)).mean(1), 
    df.index[3:], 
) 
+0

母。明確な説明をありがとう。 as_stridedは面白い機能のようです。私はその方法で遊んで、コードをより簡単に消化できるかどうかを見ていきます。 – Moondra

関連する問題