Получить первый и последний индекс подмножества Pandas DataFrame - PullRequest
1 голос
/ 14 апреля 2020

У меня есть некоторые данные в pandas DataFrame, выглядящие так:

df =
        A       B
time                               
0.1     10.0    1
0.15    12.1    2
0.19    4.0     2
0.21    5.0     2
0.22    6.0     2
0.25    7.0     1
0.3     8.1     1
0.4     9.45    2
0.5     3.0     1

На основании следующего условия я ищу универсальное c решение для поиска первого и последнего индекса каждого subset.

cond = df.B == 2

До сих пор я пытался использовать концепцию группировки, но без ожидаемого результата.

df_1 = cond.reset_index()
df_2 = df_1.groupby(df_1['B']).agg(['first','last']).reset_index()

Это вывод, который я получил.

      B       time          
              first    last
0    False    0.1      0.5
1    True     0.15     0.4

Это вывод, который мне нравится получать.

      B       time          
              first    last
0    False    0.1      0.1
1    True     0.15     0.22
2    False    0.25     0.3
3    True     0.4      0.4
3    False    0.5      0.5

Как я могу выполнить sh более или менее обобщенный c подход?

1 Ответ

0 голосов
/ 14 апреля 2020

Создать помощника Series с помощью Series.shift с Series.ne и совокупной суммой по Series.cumsum для групп по последовательным значениям, затем для агрегации используется словарь:

df_1 = df_1.reset_index()
df_1.B = df_1.B == 2
g = df_1.B.ne(df_1.B.shift()).cumsum()
df_2 = df_1.groupby(g).agg({'B':'first','time': ['first','last']}).reset_index(drop=True)

print (df_2)
       B  time      
   first first  last
0  False  0.10  0.10
1   True  0.15  0.22
2  False  0.25  0.30
3   True  0.40  0.40
4  False  0.50  0.50

Если хотите избежать MultiIndex используйте именованные агрегаты:

df_1 = df_1.reset_index()
df_1.B = df_1.B == 2
g = df_1.B.ne(df_1.B.shift()).cumsum()
df_2 = df_1.groupby(g).agg(B=('B','first'),
                           first=('time','first'),
                           last=('time','last')).reset_index(drop=True)

print (df_2)
       B  first  last
0  False   0.10  0.10
1   True   0.15  0.22
2  False   0.25  0.30
3   True   0.40  0.40
4  False   0.50  0.50
...