получить общее количество по группам для всех строк, выбранных строк и процентов от общего числа панд

1

скажем, у меня есть панда данных, называемый mydf. То есть,

import pandas as pd

mydf = pd.DataFrame({
    'type':['A','A','A', 'B','B','B', 'C'], 
    'state':['NY','CA','NY', 'NY','CA','CA', 'WY'], 
    'date':['2018-01-02','2018-01-04','2018-02-06', 
            '2018-01-01','2018-01-24','2018-02-10','2018-01-24']
})

Out[28]: 
         date state type
0  2018-01-02    NY    A
1  2018-01-04    CA    A
2  2018-02-06    NY    A
3  2018-01-01    NY    B
4  2018-01-24    CA    B
5  2018-02-10    CA    B
6  2018-01-24    WY    C

Я бы хотел, чтобы таблица подсчитывала общее количество записей по состоянию и дате (только год за месяц), для всех записей типа A для всех записей (тип A, B, C), а затем процент A в пределах каждой группы.

То есть конечным результатом будет другой кадр данных pandas со следующими столбцами и значениями:

date_ym state   total_count total_type_A    percentage
20181   CA      2           1               50
20181   NY      2           1               50
20181   WY      1           0               0
20182   CA      1           0               0
20182   NY      1           1               50

Я мог бы создать две таблицы, а затем объединить их, а затем подсчитать, но я искал более простой однострочный код...

Теги:
pandas

2 ответа

2
Лучший ответ

Другой альтернативой было бы создание функции, которая возвращает Серию с вашими желаемыми столбцами.

Полный пример:

import pandas as pd

df = pd.DataFrame({
    'type':['A','A','A', 'B','B','B', 'C'], 
    'state':['NY','CA','NY', 'NY','CA','CA', 'WY'], 
    'date':['2018-01-02','2018-01-04','2018-02-06', 
            '2018-01-01','2018-01-24','2018-02-10','2018-01-24']
})

df['date_ym'] = pd.to_datetime(df['date']).dt.strftime('%Y%#m') # switch # with - on linux

def func(x):
    cnt = len(x)
    cnt_A = sum(x == 'A')
    return pd.Series({
        'total_count': cnt,
        'total_type_A': cnt_A,
        'percentage': cnt_A/cnt*100
    })

df = df.groupby(['date_ym','state'])['type'].apply(func).unstack().reset_index()

print(df)

Возвращает:

  date_ym state  total_count  total_type_A  percentage
0   20181    CA          2.0           1.0        50.0
1   20181    NY          2.0           1.0        50.0
2   20181    WY          1.0           0.0         0.0
3   20182    CA          1.0           0.0         0.0
4   20182    NY          1.0           1.0       100.0
2

Первое преобразование датируется месяцами:

mydf["date"] = mydf["date"].dt.strftime("%Y%m")

Затем используйте groupby.agg:

def total_type_A(x):
    return sum(x == "A")

def percentage(x):
    return sum(x == "A") / len(x)

mydf.groupby(["date", "state"]).agg([len, total_type_A,  percentage])
  • 2
    Я предпочитаю это решение. Однако я бы использовал pd.to_datetime(df['date']).dt.strftime('%Y%#m') .
  • 1
    @AntonvBR спасибо за предложение
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню