расчеты между продолжением последующих групп - PullRequest
0 голосов
/ 19 сентября 2019

предположим, что у нас есть следующие dataframe

df = pd.DataFrame({'set_id': [0, 0,1,1,4,4,5,5,6,6],
                  'data': [-27, -45,-52,-65,-37, 20, 17, -45, -44, 15]})

    set_id  data
0   0       -27
1   0       -45
2   1       -52
3   1       -65
4   4       -37
5   4       20
6   5       17
7   5       -45
8   6       -44
9   6       15

Я хотел бы выполнить серию различных вычислений между парами последующих наборов, что означает, что мне нужно как-то "извлечь" dataframe s с помощьюset_id с из (0,1), (4,5), (5,6), но не (1,4).

пример последующей последовательности dataframe

    set_id  data
0   0       -27
1   0       -45
2   1       -52
3   1       -65

Я создал дополнительный столбец с sequence_id, чтобы затем использовать groupby.apply, однако set_id 5 находится в двух разных последовательностях, поэтому это не решение.

Есть ли решения?предпочтительно пандастик.

Ответы [ 3 ]

0 голосов
/ 19 сентября 2019

вы можете получить список частей кадра данных, соответствующих вашему состоянию, как показано ниже

import numpy as np
import pandas as pd

df = pd.DataFrame({'set_id': [0, 0,1,1,4,4,5,5,6,6],
                  'data': [-27, -45,-52,-65,-37, 20, 17, -45, -44, 15]})


id_sets = [(0,1), (4,5), (5,6)]
df_list = [df[np.in1d(df.set_id, id_set)] for id_set in id_sets]

for df in df_list:
    display(df)

Вывод


set_id  data
0   0   -27
1   0   -45
2   1   -52
3   1   -65

set_id  data
4   4   -37
5   4   20
6   5   17
7   5   -45

set_id  data
6   5   17
7   5   -45
8   6   -44
9   6   15
0 голосов
/ 19 сентября 2019

Если вы хотите получить индексные пары последующих значений set_id, вы можете сделать что-то вроде этого:

pairs = []
for r in df.itertuples():
    if r.set_id and r.set_id == last.set_id+1:
        pairs.append([last.Index, r.Index])
    last = r

пар затем содержит список пар индексов [[1, 2], [5, 6], [7, 8]]

или для получения подкадров:

pairs = [df.loc[x:x+1] 
    for x in range(0, df.shape[0]-1) if df.loc[x, 'set_id']==df.loc[x+1, 'set_id']-1]

пар затемсодержит список данных:

for s in pairs:
    print(s, type(s))

Output:
   set  data
1    0   -45
2    1   -52 <class 'pandas.core.frame.DataFrame'>
   set  data
5    4    20
6    5    17 <class 'pandas.core.frame.DataFrame'>
   set  data
7    5   -45
8    6   -44 <class 'pandas.core.frame.DataFrame'>
0 голосов
/ 19 сентября 2019

Вы можете сгенерировать значения групп с zip_longest с параметром fillvalue, если непарное значение уникальных значений добавляется к последнему предыдущему значению, а затем фильтруется по Series.isin:

from  itertools import zip_longest

a = df['set_id'].unique()
b = [(x, y) for x, y in zip_longest(a[::2], a[1::2], fillvalue=a[-2])]
print (b)
[(0, 1), (4, 5), (6, 5)]

for x in b:
    df1 = df[df['set_id'].isin(x)]
    print (df1)

   set_id  data
0       0   -27
1       0   -45
2       1   -52
3       1   -65
   set_id  data
4       4   -37
5       4    20
6       5    17
7       5   -45
   set_id  data
6       5    17
7       5   -45
8       6   -44
9       6    15

Другая идея заключается в добавлении последней предыдущей группы (здесь 5), если не связаны уникальные значения:

df['g'] = pd.factorize(df['set_id'])[0] // 2

max_g = df.loc[df['g'] == df['g'].max(), 'set_id']
last_prev_df = df.loc[df['g'] == df['g'].max() - 1, 'set_id']


if max_g.nunique() == 1:
    df1 = df[df['g'] !=  df['g'].max()]
    df2 = df[df['set_id'] == last_prev_df.values[-1]].assign(g = df['g'].max())
    df3 = df[df['g'] ==  df['g'].max()]

    df = pd.concat([df1, df2, df3], ignore_index=False)

Так возможно группирование по столбцу помощника g и применение пользовательской функции:

def func(x):
    print (x)

df1 = df.groupby('g').apply(func)
   set_id  data  g
0       0   -27  0
1       0   -45  0
2       1   -52  0
3       1   -65  0
   set_id  data  g
4       4   -37  1
5       4    20  1
6       5    17  1
7       5   -45  1
   set_id  data  g
6       5    17  2
7       5   -45  2
8       6   -44  2
9       6    15  2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...