Как выполнять вложенные групповые операции в кадре данных на основе условия в столбце? - PullRequest
1 голос
/ 28 мая 2019

Я должен найти количество циклов в столбце в моем фрейме данных (цикл определяется, когда переменная переходит от начального к некоторому максимальному значению и снова начинается с некоторого начального значения).Всякий раз, когда переменная имеет повторяющиеся значения, я просто усредняю ​​их.В желаемом кадре данных я добавляю номер цикла фильтра к этому SNo в качестве суффикса, чтобы узнать, в каком цикле находится данное SNo. Мне нужно получить минимальное и максимальное значения для данного цикла и SNo (оно не предопределено)

Ниже приведены пример фрейма данных и требуемого фрейма данных:

SNo  VarPer Value
1000    0   1.2
1000    1   2.2
1000    2   3.2
1000    3   4.2
1000    4   5.2
1000    4   6.2
1000    5   7.2
1000    5   8.2
1000    0   0.9
1000    1   1.9
1000    2   2.9
1000    3   3.9
1000    3   4.9
1000    4   5.9
1001    0   0.5
1001    1   1.5
1001    2   2.5
1001    2   3.5
1001    0   1
1001    1   1
1001    2   1
SNo   VarPer Value
1000_1  0   1.2
1000_1  1   2.2
1000_1  2   3.2
1000_1  3   4.2
1000_1  4   5.7
1000_1  5   7.7
1000_2  0   0.9
1000_2  1   1.9
1000_2  2   2.9
1000_2  3   4.4
1000_2  4   5.9
1001_1  0   0.5
1001_1  1   1.5
1001_1  2   3
1001_2  0   1
1001_2  1   1
1001_2  2   1

Я уже пробовал следующее:

y = dat.groupby(['SNo','VarPer'], as_index=False)['Value'].mean()

Ноэто группировка целиком без учета циклов.У меня около 70000 строк данных, поэтому мне нужно что-то не очень медленное.Пожалуйста, помогите!

1 Ответ

0 голосов
/ 29 мая 2019

Как заметил @Peter Leimbigler, мне также не совсем понятна логика генерации суффикса. Я думаю, что от 1000_3 до 1000_6 все должны быть 1000_2.

Чтобы использовать групповую передачу, вам нужно создать новую группировку с чем-то вроде этого:

for _, values in df.groupby('SNo'):
    group_label = 0
    for row in values.index:
        if df.loc[row, 'VarPer'] !=0:
            df.loc[row, 'group'] = group_label
        else:
            group_label+=1
            df.loc[row, 'group'] = group_label

РЕДАКТИРОВАТЬ: Вы, вероятно, не должны использовать цикл для записи непосредственно в фрейм данных. Вместо этого вы можете создать список, а затем создать новый столбец, используя этот список. Это будет быстрее.

new_grouping = []
for _, values in df.groupby('SNo'):
    label = 0
    group = []
    for row in values.index:
        if df.loc[row, 'VarPer'] !=0:
            group.append(label)
        else:
            label+=1
            group.append(label)
    new_grouping.extend(group)
df['group'] = new_grouping

Это не будет быстрым, но, возможно, вы (или кто-то еще) можете векторизовать это. Затем вы можете использовать groupby, чтобы получить ваши усредненные значения:

df = df.groupby(['SNo','group'],as_index = False])["VarPer"].mean().reset_index()

Если ваши суффиксы действительно должны быть такими, как я описал выше, вы можете сделать:

df['SNo'] = df['SNo'].map(str) +'_' + df['group'].map(lambda x: str(int(x)).zfill(2))

Это даст вам:

SNo  group VarPer Value
1000_1  1.0 0   1.2
1000_1  1.0 1   2.2
1000_1  1.0 2   3.2
1000_1  1.0 3   4.2
1000_1  1.0 4   5.7
1000_1  1.0 5   7.7
1000_2  2.0 0   0.9
1000_2  2.0 1   1.9
1000_2  2.0 2   2.9
1000_2  2.0 3   4.4
1000_2  2.0 4   5.9
1001_1  1.0 0   0.5
1001_1  1.0 1   1.5
1001_1  1.0 2   3.0
1001_2  2.0 0   1.0
1001_2  2.0 1   1.0
1001_2  2.0 2   1.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...