groupby по нескольким колонкам, затем подсчёт количества строк с определённым значением

Сгенерим датасет.

n = 20 
df = pd.DataFrame({ 
        'person': np.random.randint(1, 4, size=n),     
        'season': np.random.randint(1, 4, size=n), 
        'target': np.random.randint(0, 3, size=n), 
        'score': np.random.randint(0, 6, size=n), 
        })

Надо создать новую колонку:

  1. Сгруппированную по 'person', 'season'
  2. Считающую количество строк в колонке score где значение равно 0. Если таких значений нет, то ставится 0.

Мне это видится примерно как:

df['score_zero'] = df.groupby(['person', 'season'][df['score']==0]).transform('count')

либо так:

df['score_zero'] = df.groupby(['person', 'season', 'score']).df['score_in']==0].transform('count')

но получаю ошибки.


Ответы (1 шт):

Автор решения: MaxU

Исходные данные:

In [143]: df
Out[143]:
    person  season  target  score
0        1       2       2      2
1        3       1       0      1
2        1       1       0      0
3        3       3       1      5
4        2       3       1      3
5        1       1       2      4
6        1       1       2      4
7        3       2       2      3
8        2       3       2      0
9        3       1       0      3
10       2       2       0      4
11       2       2       2      4
12       2       1       0      3
13       3       1       0      0
14       3       1       0      0
15       1       3       1      4
16       1       1       1      1
17       1       3       1      2
18       2       3       0      1
19       2       1       2      4

Решение:

res = df.groupby(['person', 'season'])["score"].apply(lambda x: x.eq(0).sum())

Результат:

In [145]: res
Out[145]:
person  season
1       1         1
        2         0
        3         0
2       1         0
        2         0
        3         1
3       1         2
        2         0
        3         0
Name: score, dtype: int64

Как это перевести в новую колонку?

df["res"] = df.groupby(['person', 'season'])["score"].transform(lambda x: x.eq(0).sum())

результат:

In [163]: df
Out[163]:
    person  season  target  score  res
0        1       2       2      2    0
1        3       1       0      1    2
2        1       1       0      0    1
3        3       3       1      5    0
4        2       3       1      3    1
5        1       1       2      4    1
6        1       1       2      4    1
7        3       2       2      3    0
8        2       3       2      0    1
9        3       1       0      3    2
10       2       2       0      4    0
11       2       2       2      4    0
12       2       1       0      3    0
13       3       1       0      0    2
14       3       1       0      0    2
15       1       3       1      4    0
16       1       1       1      1    1
17       1       3       1      2    0
18       2       3       0      1    1
19       2       1       2      4    0
→ Ссылка