(半)不規則な期間でDataFrameをリサンプリングする「クックブック」の方法はありますか?
私は毎日の間隔でデータセットを持っており、それを時々(科学文献では)dekadと呼ばれるものにリサンプリングしたいと思っています。適切な英語の用語があるとは思いませんが、基本的には1か月を3〜10日の部分に分割し、3番目は8〜11日の残りの部分です。
私は自分で2つの解決策を考え出しました。1つはこの場合の特定の解決策であり、もう1つは不規則な期間のより一般的な解決策です。しかし、どちらも本当に良いものではないので、他の人がこれらのタイプの状況をどのように処理するかについては不思議です。
いくつかのサンプルデータの作成から始めましょう。
import pandas as pd
begin = pd.datetime(2013,1,1)
end = pd.datetime(2013,2,20)
dtrange = pd.date_range(begin, end)
p1 = np.random.rand(len(dtrange)) + 5
p2 = np.random.rand(len(dtrange)) + 10
df = pd.DataFrame({'p1': p1, 'p2': p2}, index=dtrange)
私が最初に思いついたのは、個々の月(YYYYMM)でグループ化し、それを手動でスライスすることです。好き:
def to_dec1(data, func):
# create the indexes, start of the ~10day period
idx1 = pd.datetime(data.index[0].year, data.index[0].month, 1)
idx2 = idx1 + datetime.timedelta(days=10)
idx3 = idx2 + datetime.timedelta(days=10)
# slice the period and perform function
oneday = datetime.timedelta(days=1)
fir = func(data.ix[:idx2 - oneday].values, axis=0)
sec = func(data.ix[idx2:idx3 - oneday].values, axis=0)
thi = func(data.ix[idx3:].values, axis=0)
return pd.DataFrame([fir,sec,thi], index=[idx1,idx2,idx3], columns=data.columns)
dfmean = df.groupby(lambda x: x.strftime('%Y%m'), group_keys=False).apply(to_dec1, np.mean)
その結果:
print dfmean
p1 p2
2013-01-01 5.436778 10.409845
2013-01-11 5.534509 10.482231
2013-01-21 5.449058 10.454777
2013-02-01 5.685700 10.422697
2013-02-11 5.578137 10.532180
2013-02-21 NaN NaN
常に1か月分の「dekads」を受け取ることに注意してください。これは問題ではなく、必要に応じて簡単に削除できます。
もう1つのソリューションは、DataFrameを切り刻み、各セグメントで関数を実行する日付の範囲を提供することで機能します。あなたが望む期間に関してそのより柔軟です。
def to_dec2(data, dts, func):
chucks = []
for n,start in enumerate(dts[:-1]):
end = dts[n+1] - datetime.timedelta(days=1)
chucks.append(func(data.ix[start:end].values, axis=0))
return pd.DataFrame(chucks, index=dts[:-1], columns=data.columns)
dfmean2 = to_dec2(df, dfmean.index, np.mean)
前の結果のインデックスを日付の範囲として使用して、自分で「構築」する時間を節約できることに注意してください。
これらのケースを処理する最良の方法は何でしょうか?パンダにはもう少し組み込みの方法がありますか?