2016-10-12 13 views
1

値:パンダDATAFRAMEシフト列は、私がデータフレーム持っ

df = pd.DataFrame({'year':[2000,2000,2000,2001,2001,2002,2002,2002],'ID':['a','b','c','a','b','a','b','c'],'values':[1,2,3,4,5,7,8,9]}) 

enter image description here

を私は例えば、各ID-年のラグ値を持つ列を作成したいです2000年のID'aの値は1であるため、2001年のID'aは1の事前値を持つ必要があります。重要なポイントは、IDが前年の値を持たない場合(つまり、年がいくつかのIDで連続していない場合)、2年前の値ではなく、事前値はNaNでなければなりません。たとえば、ID'c 'は2001年には表示されず、2002年にはID'c'は事前値= NaNになります。 理想的には、最終的な出力は、次のようになります。私はdf.groupby([ 'ID']) '値を']試みenter image description here

シフト(1)、それは以下が得られる: enter image description here

ID'c 'に1年前の値がない場合、2年前の値が使用されるという問題があります。私もマルチインデックスシフトを試してみましたが、これは私に同じ結果をもたらします。

df.set_index(['year','ID'], inplace = True) 
df.groupby(level=1)['values'].shift(1) 

答えはhereです。しかし、私のデータフレームはかなり大きいので、マージはカーネルを殺します。これまでのところ、私はそれをするより良い方法を考え出していません。私は私の問題をはっきりと説明することを願っています

答えて

2

year列が各IDに対して一意であるとします。つまり、特定のIDごとに重複年が存在しない場合、最初に値をシフトしてから、現在の行と前の行はNaN1に等しくない:

import pandas as pd 
import numpy as np 
df['pre_value'] = df.groupby('ID')['values'].shift(1) 
df['pre_value'] = df.pre_value.where(df.groupby('ID').year.diff() == 1, np.nan) 
df 

enter image description here

+0

答えてくれてありがとう、それは私の問題を解決します。私は値を置き換えることを考えていませんでした。したがって、私の年の列が他の頻度(月または四半期)の時間である場合、それらの日付の間の差異を特定の範囲(月間32、四半期93)で置き換えることができます。再度、感謝します。 – Crystie

0

reindexアプローチ

def reindex_min_max(df): 
    mn = df.year.min() 
    mx = df.year.max() + 1 
    d = df.set_index('year').reindex(pd.RangeIndex(mn, mx, name='year')) 
    return pd.concat([d, d['values'].shift().rename('pre_value')], axis=1) 

df.groupby('ID')[['year', 'values']].apply(reindex_min_max) \ 
    .sort_index(level=[1, 0]).dropna(subset=['values']).reset_index() 

enter image description here

関連する問題