Pandas сгруппировать и вычесть строки - PullRequest
2 голосов
/ 06 февраля 2020

У меня есть следующий фрейм данных:

id variable year value
1      a    2020   2
1      a    2021   3
1      a    2022   5
1      b    2020   3
1      b    2021   8
1      b    2022   10

Я хочу сгруппировать идентификатор и переменную и вычесть значения 2020 из всех строк группы. Итак, я получу:

id variable year value
1      a    2020   0
1      a    2021   1
1      a    2022   3
1      b    2020   0
1      b    2021   5
1      b    2022   7

Как я могу это сделать?

Ответы [ 2 ]

2 голосов
/ 06 февраля 2020

Используйте DataFrame.merge, если не уверены, что 2020 первый для групп:

df1 = df[df['year'].eq(2020)]
df['value'] -= df.merge(df1,how='left',on=['id','variable'],suffixes=('_',''))['value'].values
print (df)
   id variable  year  value
0   1        a  2020      0
1   1        a  2021      1
2   1        a  2022      3
3   1        b  2020      0
4   1        b  2021      5
5   1        b  2022      7

Если 2020 всегда первый для групп, используйте GroupBy.transform с GroupBy.first:

df['value'] -= df.groupby(['id','variable'])['value'].transform('first')
print (df)
   id variable  year  value
0   1        a  2020      0
1   1        a  2021      1
2   1        a  2022      3
3   1        b  2020      0
4   1        b  2021      5
5   1        b  2022      7

РЕДАКТИРОВАТЬ:

Если в данных дублируются 2020 строк на группы решение сначала удалить дубликаты и только вычесть сначала значение:

print (df)
   id variable  year  value
0   1        a  2020      3
1   1        a  2020      2
2   1        a  2022      5
3   1        b  2020      3
4   1        b  2021      8
5   1        b  2022     10

df1 = df[df['year'].eq(2020)]
df['value'] -= df.merge(df1.drop_duplicates(['id','variable']),
                        how='left',
                        on=['id','variable'],
                        suffixes=('_',''))['value'].values

print (df)
   id variable  year  value
0   1        a  2020      0
1   1        a  2020     -1
2   1        a  2022      2
3   1        b  2020      0
4   1        b  2021      5
5   1        b  2022      7

или агрегированные значения, например, sum для дедуплицированных данных:

print (df)
   id variable  year  value
0   1        a  2020      3
1   1        a  2020      1
2   1        a  2022      5
3   1        b  2020      3
4   1        b  2021      8
5   1        b  2022     10

df = df.groupby(['id','variable','year'], as_index=False).sum()
print (df)
   id variable  year  value
0   1        a  2020      4
1   1        a  2022      5
2   1        b  2020      3
3   1        b  2021      8
4   1        b  2022     10

df1 = df[df['year'].eq(2020)]
df['value'] -= df.merge(df1, how='left',
                        on=['id','variable'],
                        suffixes=('_',''))['value'].values

print (df)
   id variable  year  value
0   1        a  2020      0
1   1        a  2022      1
2   1        b  2020      0
3   1        b  2021      5
4   1        b  2022      7
1 голос
/ 06 февраля 2020

Хотя 2020 не первая группа, которую мы могли бы использовать : GroupBy.transform с Series.where

df['value']= df['value'].sub(df['value'].where(df['year'].eq(2020))
                                        .groupby([df['id'],df['variable']])
                                        .transform('max'))
print(df)
   id variable  year  value
0   1        a  2020    0.0
1   1        a  2021    1.0
2   1        a  2022    3.0
3   1        b  2020    0.0
4   1        b  2021    5.0
5   1        b  2022    7.0

если год это string вам может понадобиться

df['year'].eq('2020')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...