I want to rotate a Dataframe according to its groups and I need the Index to rotate with the rows as well. I want to do that, to then use a find_peaks function to get the peaks that are on the edges, because for me the data is kind a like a loop. Following is a df example with randome number values, where the df.groupby('Value a') is made.
idx | ValueA | ValueB |
---|---|---|
1 | a | 0.123 |
2 | a | 0.253 |
3 | a | 0.456 |
4 | a | 0.789 |
5 | a | 0.147 |
6 | b | 0.258 |
7 | b | 0.369 |
8 | b | 0.321 |
9 | b | 0.654 |
10 | b | 0.987 |
And this is how it should look like afterwards:
idx | ValueA | ValueB |
---|---|---|
4 | a | 0.789 |
5 | a | 0.147 |
1 | a | 0.123 |
2 | a | 0.253 |
3 | a | 0.456 |
9 | b | 0.654 |
10 | b | 0.987 |
6 | b | 0.258 |
7 | b | 0.369 |
8 | b | 0.321 |
I tried:
def roll_frame(df, shift):
return pd.DataFrame(np.roll(df, shift, axis=0), index=df.index, columns=df.columns)
df_new = df.groupby('Value a').apply(roll_frame, 2)
The Value is shifted correctly, but not the Index. To erase the double Index, I used:
df_new.reset_index(level=0, drop=True, inplace=True)
which resulted in this:
idx | ValueA | ValueB |
---|---|---|
1 | a | 0.789 |
2 | a | 0.147 |
3 | a | 0.123 |
4 | a | 0.253 |
5 | a | 0.456 |
6 | b | 0.654 |
7 | b | 0.987 |
8 | b | 0.258 |
9 | b | 0.369 |
10 | b | 0.321 |
The easiest way I can think of would be to np.roll()
the index as well:
def roll_frame(df, shift):
return pd.DataFrame(
np.roll(df, shift, axis=0), index=np.roll(df.index, shift), columns=df.columns
)
df_new = df.groupby("ValueA").apply(roll_frame, 2)
print(df_new)
Prints:
ValueA ValueB
ValueA
a 4 a 0.789
5 a 0.147
1 a 0.123
2 a 0.253
3 a 0.456
b 9 b 0.654
10 b 0.987
6 b 0.258
7 b 0.369
8 b 0.321