Suppose I have a data frame
Sym C O R
01.01.2020 AAPL 100 115 0.2
01.01.2020 AA 200 205 0.4
02.01.2020 AAPL 101 116 0.3
02.01.2020 AA 201 206 0.2
02.01.2020 MM 298 300 0.5
03.01.2020 AAPL 110 105 0.3
03.01.2020 AA 203 204 0.1
03.01.2020 MM 301 303 0.2
04.01.2020 AAPL 108 113 0.3
04.01.2020 AA 200 201 0.4
04.01.2020 MM 302 300 0.3
How can I make a new data frame which will make the new columns for each previous date and be shifted for 3 periods?
I would expect
Sym C_1 O_1 R_1 C_2 O_2 R_2 C_3 O_3 R_3
01.01.2020 AAPL NaN NaN ... NaN
01.01.2020 AA NaN NaN ... NaN
02.01.2020 AAPL 100 115 0.2 NaN NaN NaN NaN NaN NaN
02.01.2020 AA 200 205 0.4 NaN NaN NaN NaN NaN NaN
02.01.2020 MM NaN NaN ... NaN
03.01.2020 AAPL 101 116 0.3 100 115 0.2 NaN NaN NaN
03.01.2020 AA 201 206 0.2 200 205 0.4 NaN NaN NaN
03.01.2020 MM 298 300 0.5 NaN NaN .. NaN
04.01.2020 AAPL 101 116 0.3 100 115 0.2 110 105 0.3
04.01.2020 AA 203 204 0.1 201 206 0.2 200 205 0.4
04.01.2020 MM 301 303 0.2 298 300 0.5 Nan NaN NaN
The answer provided in Use pandas.shift() within a group does not give what I expect. I tried also:
def shift_data (df):
df= df.shift(3)
return df
data.groupby('Sym', group_keys=False).apply(shift_data) #
CodePudding user response:
Combine groupby.shift
and pandas.concat
:
N = 3
out = pd.concat([df[['Sym']]]
[df.groupby('Sym').shift(i).add_suffix(f'_{i}')
for i in range(1, N 1)], axis=1)
Output:
Sym C_1 O_1 R_1 C_2 O_2 R_2 C_3 O_3 R_3
01.01.2020 AAPL NaN NaN NaN NaN NaN NaN NaN NaN NaN
01.01.2020 AA NaN NaN NaN NaN NaN NaN NaN NaN NaN
02.01.2020 AAPL 100.0 115.0 0.2 NaN NaN NaN NaN NaN NaN
02.01.2020 AA 200.0 205.0 0.4 NaN NaN NaN NaN NaN NaN
02.01.2020 MM NaN NaN NaN NaN NaN NaN NaN NaN NaN
03.01.2020 AAPL 101.0 116.0 0.3 100.0 115.0 0.2 NaN NaN NaN
03.01.2020 AA 201.0 206.0 0.2 200.0 205.0 0.4 NaN NaN NaN
03.01.2020 MM 298.0 300.0 0.5 NaN NaN NaN NaN NaN NaN
04.01.2020 AAPL 110.0 105.0 0.3 101.0 116.0 0.3 100.0 115.0 0.2
04.01.2020 AA 203.0 204.0 0.1 201.0 206.0 0.2 200.0 205.0 0.4
04.01.2020 MM 301.0 303.0 0.2 298.0 300.0 0.5 NaN NaN NaN
CodePudding user response:
for column in ['C','O','R']:
df[f'{column}_1']=df.groupby('Date')[column].transform(lambda x:x.shift(1))
df[f'{column}_2']=df.groupby('Date')[column].transform(lambda x:x.shift(2))
df[f'{column}_3']=df.groupby('Date')[column].transform(lambda x:x.shift(3))
CodePudding user response:
I guess this approach works:
for i in range(3):
for column_name in ['C', 'R', 'O']:
data[column_name '_' str(i 1)] = data.groupby(['Sym'])[column_name].shift(i 1)
but make sure your dataframe is sorted!