私は、さまざまな項目に関するデータを含む大きな pandas データフレーム (〜 1,300 万行) を持っており、それぞれにさまざまな月からの観測が含まれています。項目は、対応する行の数 (観測データのある月) によって異なり、月が連続している場合と連続していない場合があります。非常に簡略化された単純化されたサンプル:
x y
item_id date
4 2006-01-01 5.69368 0.789752
2006-02-01 5.67199 0.786743
2006-03-01 5.66469 0.783626
2006-04-01 5.69427 0.782596
2006-05-01 5.70198 0.781670
5 2006-05-01 3.16992 1.000000
2006-07-01 3.25000 0.978347
データに対して達成する必要があるのは次のとおりです。各アイテムについて、そのアイテムの最初の観測行から指定された最大日付まで、フィル観測を転送します。したがって、上記の例を考えると、目的の出力は次のようになります。
x y
item_id
4 2006-01-01 5.69368 0.789752
2006-02-01 5.67199 0.786743
2006-03-01 5.66469 0.783626
2006-04-01 5.69427 0.782596
2006-05-01 5.70198 0.781670
2006-06-01 5.70198 0.781670
2006-07-01 5.70198 0.781670
2006-08-01 5.70198 0.781670
2006-09-01 5.70198 0.781670
2006-10-01 5.70198 0.781670
2006-11-01 5.70198 0.781670
2006-12-01 5.70198 0.781670
5 2006-05-01 3.16992 1.000000
2006-06-01 3.16992 1.000000
2006-07-01 3.25000 0.978347
2006-08-01 3.25000 0.978347
2006-09-01 3.25000 0.978347
2006-10-01 3.25000 0.978347
2006-11-01 3.25000 0.978347
2006-12-01 3.25000 0.978347
さらなる分析を容易にするために、最終結果が次のようになるように、日付インデックスを単純な数値インデックス (「seq」と呼びます) に変換する必要があります。
x y
item_id seq
4 0 5.69368 0.789752
1 5.67199 0.786743
2 5.66469 0.783626
3 5.69427 0.782596
4 5.70198 0.781670
5 5.70198 0.781670
6 5.70198 0.781670
7 5.70198 0.781670
8 5.70198 0.781670
9 5.70198 0.781670
10 5.70198 0.781670
11 5.70198 0.781670
5 0 3.16992 1.000000
1 3.16992 1.000000
2 3.25000 0.978347
3 3.25000 0.978347
4 3.25000 0.978347
5 3.25000 0.978347
6 3.25000 0.978347
7 3.25000 0.978347
(これのポイントは、アイテム間で最初、2 番目、...、n 番目の観察を平均できるようにすることです)。いずれにせよ、データのサブセットのみを操作する場合にうまく機能する解決策があります。
df = pd.read_table(filename,sep='\s*',header=None,names=['item_id','date','x','y'],index_col=['item_id','date'],parse_dates='date')
maxDate = '2006-12-01'
def switchToSeqIndex(df):
minDate = df.index[0][1] # get the first observed date
return df.reset_index(level='item_id',drop=True).reset_index(). \
set_index('date').reindex(pd.date_range(minDate,maxDate,freq='MS'), \
method='ffill').reset_index('date',drop=True)
df_fixed = df.groupby(level='item_id').apply(switchToSeqIndex)
df_fixed.index.names[1]='seq'
原則として、これは素晴らしいことであり、正しい出力を生成しますが、完全なデータセット (1,300 万行、再インデックス化によってかなりの量が拡張された) に対して操作を実行しようとすると、メモリ使用量が制御不能になります (マシンをクラッシュさせる20GB RAM)。
私の質問は、メモリのオーバーヘッドを減らしながらこれを達成する方法です。問題は groupby/apply メソッドで再インデックスを実行しようとしていると思いますが、代替手段が何であるかはわかりません。必要なメモリが少なくて済むように、同様のことを繰り返し行う方法があるはずですが、どうすればよいかわかりません。