web-dev-qa-db-ja.com

pandas in Python

以下のようなDataFrame保存の毎日のデータがあります:

Date              Open        High         Low       Close   Volume
2010-01-04   38.660000   39.299999   38.509998   39.279999  1293400   
2010-01-05   39.389999   39.520000   39.029999   39.430000  1261400   
2010-01-06   39.549999   40.700001   39.020000   40.250000  1879800   
2010-01-07   40.090000   40.349998   39.910000   40.090000   836400   
2010-01-08   40.139999   40.310001   39.720001   40.290001   654600   
2010-01-11   40.209999   40.520000   40.040001   40.290001   963600   
2010-01-12   40.160000   40.340000   39.279999   39.980000  1012800   
2010-01-13   39.930000   40.669998   39.709999   40.560001  1773400   
2010-01-14   40.490002   40.970001   40.189999   40.520000  1240600   
2010-01-15   40.570000   40.939999   40.099998   40.450001  1244200   

私がやろうとしているのは、それを週単位のデータにマージすることです。グループ化後:

  1. Dateは毎週月曜日でなければなりません(この時点では、月曜日が取引日ではない場合、休日のシナリオを考慮する必要があります。現在の週の最初の取引日を日付として適用する必要があります)。
  2. Open月曜日(または現在の週の最初の取引日)のオープンである必要があります。
  3. Closeは金曜日(または今週の最後の取引日)の終値でなければなりません。
  4. Highは、今週の取引日の最高値です。
  5. 安値は、今週の取引日の最低安値でなければなりません。
  6. ボリュームは、今週の取引日のすべてのボリュームの合計です。

これは次のようになります。

Date              Open        High         Low       Close   Volume
2010-01-04   38.660000   40.700001   38.509998   40.290001  5925600   
2010-01-11   40.209999   40.970001   39.279999   40.450001  6234600   

現在、私のコードスニペットは次のとおりです。日単位のデータを予想される週単位のデータにマッピングするには、どの関数を使用すればよいですか?どうもありがとう!

import pandas_datareader.data as web

start = datetime.datetime(2010, 1, 1)
end = datetime.datetime(2016, 12, 31)
f = web.DataReader("MNST", "yahoo", start, end, session=session)
print f
9
Judking

次のように、resample(毎週)、offset(シフト)、およびapply集約ルールを使用できます。

logic = {'Open'  : 'first',
         'High'  : 'max',
         'Low'   : 'min',
         'Close' : 'last',
         'Volume': 'sum'}

offset = pd.offsets.timedelta(days=-6)

f = pd.read_clipboard(parse_dates=['Date'], index_col=['Date'])
f.resample('W', loffset=offset).apply(logic)

取得するため:

                 Open       High        Low      Close   Volume
Date                                                           
2010-01-04  38.660000  40.700001  38.509998  40.290001  5925600
2010-01-11  40.209999  40.970001  39.279999  40.450001  6234600
10
Stefan

一般に、指定した形式のデータフレームがあると想定して、次の手順を実行する必要があります。

  1. インデックスにDateを入れます
  2. resampleインデックス。

あなたが持っているのは、異なる関数を異なる列に適用する場合です。 参照

さまざまな方法でリサンプリングできます。例えば値の平均を取ったり、カウントしたりできます。チェック pandas resample

カスタムアグリゲーターを適用することもできます(同じリンクを確認してください)。これを念頭に置いて、ケースのコードスニペットは次のように指定できます。

f['Date'] = pd.to_datetime(f['Date'])
f.set_index('Date', inplace=True)
f.sort_index(inplace=True)

def take_first(array_like):
    return array_like[0]

def take_last(array_like):
    return array_like[-1]

output = f.resample('W',                                 # Weekly resample
                    how={'Open': take_first, 
                         'High': 'max',
                         'Low': 'min',
                         'Close': take_last,
                         'Volume': 'sum'}, 
                    loffset=pd.offsets.timedelta(days=-6))  # to put the labels to Monday

output = output[['Open', 'High', 'Low', 'Close', 'Volume']]

ここで、Wは、デフォルトで月曜日から日曜日までの週ごとのリサンプリングを意味します。ラベルを月曜日に保つには、loffsetを使用します。定義済みの日指定子がいくつかあります。 pandas offsets を見てください。カスタムオフセットを定義することもできます( see )。

リサンプリング法に戻ります。ここでOpenCloseの場合、最初の値などを取るカスタムメソッドを指定して、関数ハンドルをhow引数に渡すことができます。

この回答は、データが毎日のように見える、つまり、毎日1つのエントリしかないという仮定に基づいています。また、非営業日のデータはありません。つまり、土曜日と日曜日。したがって、週の最後のデータポイントを金曜日のデータポイントとしても問題ありません。必要に応じて、「W」の代わりに営業週を使用できます。また、より複雑なデータの場合、groupbyを使用して週次データをグループ化し、その中の時間インデックスを処理することができます。

ところで、ソリューションの要点は次の場所にあります https://Gist.github.com/prithwi/339f87bf9c3c37bb3188

11
goofd

直接的な回答ではありませんが、列は日付が欠落していない日付(テーブルの転置)であるとします。

'''sum up daily results in df to weekly results in wdf'''
wdf = pd.DataFrame(index = df.index)
for i in range(len(df.columns)):
    if (i!=0) & (i%7==0):
        wdf['week'+str(i//7)]= df[df.columns[i-7:i]].sum(axis = 1)
0
L. Astola