0

I have a pandas dataframe with this type of structure:

df
Val1 Val2 Col1 Col2
1    1    0    3
1    2    2    4
2    1    2    3
3    2    2    5
1    2    3    4
2    1    3    1
3    4    2    1

Basically, I sort the data frame according to the values of val1 and val2 beforehand, so I know I'll have two ascending sequences afterwards. What I want is to split this df in two new dfs, according to the two sequences, which in my example would be this:

df1
Val1 Val2 Col1 Col2
1    1    0    3
1    2    2    4
2    1    2    3
3    2    2    5

df2
Val1 Val2 Col1 Col2
1    2    3    4
2    1    3    1
3    4    2    1

I have checked this question and this, but I don't know the number of values/rows beforehand... I've also checked another question, so I thought about using split with a regular expression. But I only know the sequences will be ascending, there's no guarantee that the values will be continuous, so it doesn't work as expected.

Is this possible to achieve? I appreciate in advance any help!

xzxz
  • 75
  • 5

2 Answers2

2

Do you know that there will be only 2 sequences? If so:

mask = df.Val1 < df.Val1.shift(1)
change_point = mask[mask].index[0]
df1 = df[df.index < change_point]
df2 = df[df.index >= change_point].reset_index(drop=True)

Then df1 will be

   Val1  Val2  Col1  Col2
0     1     1     0     3
1     1     2     2     4
2     2     1     2     3
3     3     2     2     5

and df2

   Val1  Val2  Col1  Col2
0     1     2     3     4
1     2     1     3     1
2     3     4     2     1
ignoring_gravity
  • 6,677
  • 4
  • 32
  • 65
1

Using Series.shift and Series.cumsum:

m = df['Val1'].shift() > df['Val1']
dfs = [df for _, df in df.groupby(m.cumsum())]

Now we have each df in a list, we can access them:

print(dfs[0])
print(dfs[1])

   Val1  Val2  Col1  Col2
0     1     1     0     3
1     1     2     2     4
2     2     1     2     3
3     3     2     2     5 

   Val1  Val2  Col1  Col2
4     1     2     3     4
5     2     1     3     1
6     3     4     2     1
Erfan
  • 40,971
  • 8
  • 66
  • 78