Вычислите %-отклонение со значениями из фрейма данных pandas Dataframe

Я довольно новичок в python и у меня есть следующий фрейм данных

    setting_id  subject_id  seconds  result_id  owner_id  average  duration_id
0            7           1        0     1680.5       2.0   24.000          1.0
1            7           1     3600     1690.5       2.0   46.000          2.0
2            7           1    10800     1700.5       2.0  101.000          4.0
3            7           2        0     1682.5       2.0   12.500          1.0
4            7           2     3600     1692.5       2.0   33.500          2.0
5            7           2    10800     1702.5       2.0   86.500          4.0
6            7           3        0     1684.5       2.0    8.500          1.0
7            7           3     3600     1694.5       2.0   15.000          2.0
8            7           3    10800     1704.5       2.0   34.000          4.0

Мне нужно сделать следующее Вычислить отклонение (%) от средних значений со значением "seconds" не равным 0 от средних значений со значением seconds равным нулю, где subject_id и Setting_id одинаковы

т.е. setting_id ==7 & subject_id ==1 будет:

(result/baseline)*100

------> в течение 3600 секунд: (46/24)*100 = +192%

------> в течение 10800 секунд: (101/24)*100 = +421%

.... базовый уровень = средний результат со значением секунд 0

.... result = average-result со значением секунд, отличным от 0

Результат df должен выглядеть следующим образом

   setting_id  subject_id  seconds  owner_id  average  deviation  duration_id
0           7           1        0         2       24          0            1
1           7           1     3600         2       46        192            2
2           7           1    10800         2      101        421            4

Я хочу использовать эти расчеты для построения графика регрессии (с сиборном) отклонений от базовой линии

Я играю с этим df уже 2 дня и пробовал различные forloops, но я просто не могу понять правильный путь.

Вы можете использовать:

# identify rows with 0
m = df['seconds'].eq(0)
# compute the sum of rows with 0
s = (df['average'].where(m)
     .groupby([df['setting_id'], df['subject_id']])
     .sum()
    )

# compute the deviation per group
deviation = (
 df[['setting_id', 'subject_id']]
 .merge(s, left_on=['setting_id', 'subject_id'], right_index=True, how='left')
 ['average']
 .rdiv(df['average']).mul(100)
 .round().astype(int) # optional
 .mask(m, 0)
)

df['deviation'] = deviation
# or
# out = df.assign(deviation=deviation)

Выход:

   setting_id  subject_id  seconds  result_id  owner_id  average  duration_id  deviation
0           7           1        0     1680.5       2.0     24.0          1.0          0
1           7           1     3600     1690.5       2.0     46.0          2.0        192
2           7           1    10800     1700.5       2.0    101.0          4.0        421
3           7           2        0     1682.5       2.0     12.5          1.0          0
4           7           2     3600     1692.5       2.0     33.5          2.0        268
5           7           2    10800     1702.5       2.0     86.5          4.0        692
6           7           3        0     1684.5       2.0      8.5          1.0          0
7           7           3     3600     1694.5       2.0     15.0          2.0        176
8           7           3    10800     1704.5       2.0     34.0          4.0        400
Вернуться на верх