2017-11-04 3 views
-1

私はこのようになりますこれは、パンダのデータフレームに格納される時系列データをしました:パンダのパラメータとしてスライディングウィンドウでスライスしたデータフレームを取得する関数を適用するにはどうすればよいですか?

Date   Open High Low  Close Volume 
0 2016-01-19 22.86 22.92 22.36 22.60 838024 
1 2016-01-20 22.19 22.98 21.87 22.77 796745 
2 2016-01-21 22.75 23.10 22.62 22.76 573068 
3 2016-01-22 23.13 23.35 22.96 23.33 586967 
4 2016-01-25 23.22 23.42 23.01 23.26 645551 
5 2016-01-26 23.28 23.85 23.22 23.74 592658 
6 2016-01-27 23.68 23.78 18.76 20.09 5351850 
7 2016-01-28 20.05 20.69 19.11 19.37 2255635 
8 2016-01-29 19.51 20.02 19.40 19.90 1203969 
9 2016-02-01 19.77 19.80 19.13 19.14 1203375 

私はそれが任意のカスタム定義されたことにより、集約することができるもの、元のデータセットのスライスを取得し、該当する機能を、作成したいです集約演算子。 calculateMySpecificAggregationは、元のデータフレームの行ごとに、元のデータフレームの3サイズのスライスを取得

aggregated_df = data.apply(calculateMySpecificAggregation, axis=1) 

言うでき、関数は次のように適用されます。 各行について、関数のパラメータデータフレームは元のデータフレームの前の行と次の行を含みます。

#pseudocode example 
def calculateMySpecificAggregation(df_slice): 

    # I want to know which row was this function applied on (an index I would like to have here) 
    ri= ??? # index of the row where was this function applied 

    # where df_slice contains 3 rows and all columns 
    return float(df_slice["Close"][ri-1] + \ 
       ((df_slice["High"][ri] + df_slice["Low"][ri])/2) + \ 
       df_slice["Open"][ri+1]) 
    # this line will fail on the borders, but don't worry, I will handle it later... 

Iは、パラメータ化スライディングウィンドウサイズを有する行の他の列へのアクセス機能がオンに適用された元の行の行インデックスを知りたいです。意味

は、= 3 slidingWindowの場合には、私は、パラメータデータフレームを持つようにしたい:

#parameter dataframe when the function is applied on row[0]: 
    Date   Open High Low  Close Volume 
0 2016-01-19 22.86 22.92 22.36 22.60 838024 
1 2016-01-20 22.19 22.98 21.87 22.77 796745 

#parameter dataframe when the function is applied on row[1]: 
    Date   Open High Low  Close Volume 
0 2016-01-19 22.86 22.92 22.36 22.60 838024 
1 2016-01-20 22.19 22.98 21.87 22.77 796745 
2 2016-01-21 22.75 23.10 22.62 22.76 573068 

#parameter dataframe when the function is applied on row[2]: 
    Date   Open High Low  Close Volume 
1 2016-01-20 22.19 22.98 21.87 22.77 796745 
2 2016-01-21 22.75 23.10 22.62 22.76 573068 
3 2016-01-22 23.13 23.35 22.96 23.33 586967 

#parameter dataframe when the function is applied on row[3]: 
    Date   Open High Low  Close Volume 
2 2016-01-21 22.75 23.10 22.62 22.76 573068 
3 2016-01-22 23.13 23.35 22.96 23.33 586967 
4 2016-01-25 23.22 23.42 23.01 23.26 645551 

...    

#parameter dataframe when the function is applied on row[7]: 
    Date   Open High Low  Close Volume 
6 2016-01-27 23.68 23.78 18.76 20.09 5351850 
7 2016-01-28 20.05 20.69 19.11 19.37 2255635 
8 2016-01-29 19.51 20.02 19.40 19.90 1203969 

#parameter dataframe when the function is applied on row[8]: 
    Date   Open High Low  Close Volume 
7 2016-01-28 20.05 20.69 19.11 19.37 2255635 
8 2016-01-29 19.51 20.02 19.40 19.90 1203969 
9 2016-02-01 19.77 19.80 19.13 19.14 120375 

#parameter dataframe when the function is applied on row[9]: 
    Date   Open High Low  Close Volume 
8 2016-01-29 19.51 20.02 19.40 19.90 1203969 
9 2016-02-01 19.77 19.80 19.13 19.14 1203375 

私は、可能な場合ilocインデックスとコンバインドサイクルを使用する必要はありません。

私はpandas.DataFrame.rollingpandas.rolling_applyを試してみましたが、成功しませんでした。

誰もこの問題を解決する方法を知っていますか?

答えて

0

私はこの問題を解決しました。 iloc(この場合は大きな問題ではありません)を避けることはできませんでしたが、ここでは少なくともサイクルは使用されていません。

contextSizeLeft = 2 
contextSizeRight = 3 

def aggregateWithContext(df, row, func, contextSizeLeft, contextSizeRight): 

    leftBorder = max(0,  row.name - contextSizeLeft) 
    rightBorder = min(len(df), row.name + contextSizeRight) + 1 

    ''' 
    print("pos: ", row.name, \ 
      "\t", (row.name-contextSizeLeft, row.name+contextSizeRight), \ 
      "\t", (leftBorder, rightBorder), \ 
      "\t", len(df.loc[:][leftBorder : rightBorder])) 
    ''' 

    return func(df.iloc[:][leftBorder : rightBorder], row.name) 

def aggregate(df, center): 
    print() 
    print("center", center) 
    print(df["Date"]) 
    return len(df) 


df.apply(lambda x: aggregateWithContext(df, x, aggregate, contextSizeLeft, contextSizeRight), axis=1) 

と日付の同じ誰もがそれを必要とする場合:

def aggregateWithContext(df, row, func, timedeltaLeft, timedeltaRight): 

    dateInRecord = row["Date"] 
    leftBorder = pd.to_datetime(dateInRecord - timedeltaLeft) 
    rightBorder = pd.to_datetime(dateInRecord + timedeltaRight) 

    dfs = df[(df['Date'] >= leftBorder) & (df['Date'] <= rightBorder)] 
    #print(dateInRecord, ":\t", leftBorder, "\t", rightBorder, "\t", len(dfs)) 

    return func(dfs, row.name) 

def aggregate(df, center): 
    #print() 
    #print("center", center) 
    #print(df["Date"]) 
    return len(df) 


timedeltaLeft = timedelta(days=2) 
timedeltaRight = timedelta(days=2) 
df.apply(lambda x: aggregateWithContext(df, x, aggregate, timedeltaLeft, timedeltaRight), axis=1) 
関連する問題