我想详细说明分组逻辑如下。给定数据框df
:
df =
ID GROUP DAY GRADE TIME_1
1 AAA 1 5 20
1 AAA 1 4 19
1 AAA 1 3 21
1 BBB 2 1 10
2 BBB 2 3 13
我需要按ID
,GRADE
,GROUP
和DAY
对行进行分组,并计算平均值TIME_1
,即组中的行数。另外(这是我的问题),我想检查GRADE
是4还是5,那么它应该被分组为正数,并且应该根据它计算平均TIME_1
,否则 - 作为负数
结果应该是这个:
result =
GROUP DAY AVG_TIME_1_POSITIVE AVG_TIME_1_NEGATIVE QTY_POSITIVE QTY_NEGATIVE
AAA 1 19.5 21 2 1
BBB 2 0 11.5 0 2
我使用这种方法,但不知道如何通过GRADE
指定分组条件:
result = df.groupby(['GROUP','GRADE','DAY']).agg({'TIME_1': 'mean',
'ID': 'count'}).reset_index()
答案 0 :(得分:2)
一种可能的解决方案是boolean indexing
,然后使用concat
:
mask = df.GRADE.isin([4,5])
result1 = df[mask].groupby(['GROUP','DAY']).agg({'TIME_1': 'mean',
'ID': 'count'}).add_suffix('_POSITIVE')
print (result1)
TIME_1_POSITIVE ID_POSITIVE
GROUP DAY
AAA 1 19.5 2
result2 = df[~mask].groupby(['GROUP','DAY']).agg({'TIME_1': 'mean',
'ID': 'count'}).add_suffix('_NEGATIVE')
print (result2)
TIME_1_NEGATIVE ID_NEGATIVE
GROUP DAY
AAA 1 21.0 1
BBB 2 11.5 2
print (pd.concat([result1, result2], axis=1))
TIME_1_POSITIVE ID_POSITIVE TIME_1_NEGATIVE ID_NEGATIVE
GROUP DAY
AAA 1 19.5 2.0 21.0 1
BBB 2 NaN NaN 11.5 2
答案 1 :(得分:2)
您还可以将功能传递给agg
类似
qty_pos = df.groupby(['GROUP','GRADE','DAY']).agg({'GRADE': lambda x: sum(x>3)})
qty_neg = df.groupby(['GROUP','GRADE','DAY']).agg({'GRADE': lambda x: sum(x<=3)})
result['QTY_POSITIVE'] = qty_pos
result['QTY_NEGATIV'] = qty_neg
答案 2 :(得分:0)
对我来说,如果你必须在使用groupby之后手动拆分,应用和组合数据帧,那么它就不是pythonic(我们应该为我们执行split-apply-combine作业)。所以我认为问题是如何为数据集分组制定一个合适的密钥。
输入:
df=df.set_index(['GROUP','DAY', 'GRADE'],drop=False)
key=lambda x: (x[0],x[1], 'positive' if x[2] in [4,5] else 'negative')
df.groupby(key).agg({'TIME_1': 'mean', 'ID': 'count'})
输出:
TIME_1 ID
(AAA, 1, negative) 21.0 1
(AAA, 1, positive) 19.5 2
(BBB, 2, negative) 11.5 2