#python #pandas #pandas-groupby
#python #pandas #pandas-groupby
Вопрос:
У меня есть массив groupby, в котором мне нужно сгруппировать по A, затем показать количество экземпляров B, разделенных B1 и B2, и, наконец, процент тех экземпляров, которые > 0,1, поэтому я сделал это, чтобы получить первые 2:
A B C
id
118 a1 B1 0
119 a1 B1 0
120 a1 B1 101.1
121 a1 B1 106.67
122 a1 B2 103.33
237 a1 B2 100
df = pd.DataFrame(df.groupby(
['A', 'B'])['B'].aggregate('count')).unstack(level=1)
к которому я правильно понял первую часть:
B
B B1 B2
A
a1 4 2
a2 7 9
a3 9 17
a4 8 8
a5 7 8
Но затем, когда мне нужно получить процент от количества, которое равно > 0
prcnt_complete = df[['A', 'B', 'C']]
prcnt_complete['passed'] = prcnt_complete['C'].apply(lambda x: (float(x) > 1))
prcnt_complete = prcnt_complete.groupby(['A', 'B', 'passed']).count()
Я получаю странные значения, которые не имеют смысла, иногда сумма между True и False даже не складывается. Я пытаюсь понять, что в порядке вещей я делаю неправильно, чтобы я мог понять это.
Результат, который я ищу, выглядит примерно так:
B passed
B B1 B2 B1 B2
A
a1 4 2 2 2
a2 7 9 7 6
a3 9 17 9 5
Спасибо,
Ответ №1:
Вы можете сделать:
(df['C'].gt(1).groupby([df['A'],df['B']])
.agg(['size','sum'])
.rename(columns={'size':'B','sum':'passed'})
.unstack('B')
)
Вывод (из образца данных):
B passed
B B1 B2 B1 B2
A
a1 4 2 2 2
Ответ №2:
Работая над вашей проблемой, я также хотел посмотреть, смогу ли я получить средний процент для B (игнорируя 0s). Я также смог выполнить это при получении подсчетов.
Фрейм данных для этого упражнения:
A B C
0 a1 B1 0.00
1 a1 B1 0.00
2 a1 B1 98.87
3 a1 B1 101.10
4 a1 B2 106.67
5 a1 B2 103.00
6 a2 B1 0.00
7 a2 B1 0.00
8 a2 B1 33.00
9 a2 B1 100.00
10 a2 B2 80.00
11 a3 B1 90.00
12 a3 B2 99.00
Усредняет, исключая нули
для этого мне пришлось добавить .replace(0, np.nan)
перед функцией groupby.
A = ['a1','a1','a1','a1','a1','a1','a2','a2','a2','a2','a2','a3','a3']
B = ['B1','B1','B1','B1','B2','B2','B1','B1','B1','B1','B2','B1','B2']
C = [0,0,98.87,101.1,106.67,103,0,0,33,100,80,90,99]
import pandas as pd
import numpy as np
df = pd.DataFrame({'A':A,'B':B,'C':C})
df = pd.DataFrame(df.replace(0, np.nan)
.groupby(['A', 'B'])
.agg({'B':'size','C':['count','mean']})
.rename(columns={'size':'Count','count':'Passed','mean':'Avg Score'})).unstack(level=1)
df.columns = df.columns.droplevel(0)
Count Passed Avg Score
B B1 B2 B1 B2 B1 B2
A
a1 4 2 2 2 99.985 104.835
a2 4 1 2 1 66.500 80.000
a3 1 1 1 1 90.000 99.000