Групповой счет считается только тогда, когда определенное значение присутствует в одном из столбцов в пандах - PullRequest
0 голосов
/ 05 ноября 2018

У меня есть датафрейм, аналогичный приведенной ниже базе данных:

+------------+-----+--------+ | time | id | status | +------------+-----+--------+ | 1451606400 | id1 | Yes | | 1451606400 | id1 | Yes | | 1456790400 | id2 | No | | 1456790400 | id2 | Yes | | 1456790400 | id2 | No | +------------+-----+--------+

Я группирую по всем столбцам, упомянутым выше, и я могу получить счет в другом столбце с именем 'count', используя следующую команду:

df.groupby(['time','id', 'status']).size().reset_index(name='count')

Но я хочу, чтобы число в приведенном выше кадре данных только в тех строках с status = 'Yes', а остальные должны быть '0'

Желаемый вывод:

+------------+-----+--------+---------+ | time | id | status | count | +------------+-----+--------+---------+ | 1451606400 | id1 | Yes | 2 | | 1456790400 | id2 | Yes | 1 | | 1456790400 | id2 | No | 0 | +------------+-----+--------+---------+

Я пытался сосчитать status = 'Yes' с кодом ниже:

df[df['status']== 'Yes'].groupby(['time','id','status']).size().reset_index(name='count')

, который, очевидно, дает мне эти строки с status = 'Yes' и отбрасывает остальные. Я хочу сброшенные с count = 0

Есть ли способ получить результат?

Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 05 ноября 2018

Если вы не против немного другого формата вывода, вы можете pd.crosstab:

df = pd.DataFrame({'time': [1451606400]*2 + [1456790400]*3,
                   'id': ['id1']*2 + ['id2']*3,
                   'status': ['Yes', 'Yes', 'No', 'Yes', 'No']})

res = pd.crosstab([df['time'], df['id']], df['status'])

print(res)

status          No  Yes
time       id          
1451606400 id1   0    2
1456790400 id2   2    1

Результатом является более эффективный способ хранения ваших данных, поскольку вы не повторяете свой индекс в отдельной строке для каждой категории «Да» / «Нет».

0 голосов
/ 05 ноября 2018

Использование лямбда-функции с apply и для подсчета sum логические True значения обрабатываются как 1:

df1 = (df.groupby(['time','id','status'])
         .apply(lambda x: (x['status']== 'Yes').sum())
         .reset_index(name='count'))

Или создать новый столбец и объединить sum:

df1 = (df.assign(A=df['status']=='Yes')
         .groupby(['time','id','status'])['A']
         .sum()
         .astype(int)
         .reset_index(name='count'))

Очень похожее решение без нового столбца, но немного хуже для чтения:

df1 = ((df['status']=='Yes')
        .groupby([df['time'],df['id'],df['status']])
        .sum()
        .astype(int)
        .reset_index(name='count'))

print (df)
         time   id status  count
0  1451606400  id1    Yes      2
1  1456790400  id2     No      0
2  1456790400  id2    Yes      1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...