3

私は、さまざまな項目に関するデータを含む大きな 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 メソッドで再インデックスを実行しようとしていると思いますが、代替手段が何であるかはわかりません。必要なメモリが少なくて済むように、同様のことを繰り返し行う方法があるはずですが、どうすればよいかわかりません。

4

1 に答える 1

0

DataFrame必要な日付の完全なセットを含むを作成することで、これを解決します。次に、オリジナルを ID でグループ化し、日付を使用しDataFrameて結合し、欠落している日付を取り込みます (その結果、日付を結合で取り込む必要のある行になります) 。DataFrameouterxyNaN

その後、ID でグループ化し、必要な順序で日付で並べ替えてから、通常の呼び出しを使用して、および列fillnaのすべての NaN 値を転送します。xy

私はDataFrame以前に 2 億行を超える s を使用してこの種のタスクを実行しました (12 GB の RAM を搭載したシステム上)。

擬似コード:

df = your_current_df.reset_index().set_index("item_id")
# Or, use something smarter with unstack(level=1) and possibly some 
# in-place option.

# I assume this puts the dates into a regular column called 'date'

# Do stuff to make all the dates you could possibly need
dates_df = pandas.DataFrame(...)

df = pandas.merge(df, dates_df, left_on="date", right_on="date", how="outer")
df.sort("date", ascending=True, inplace=True)
df.groupby("item_id").fillna(method="ffill")
于 2013-11-01T20:54:52.310 に答える