Pandas groupby 列并检查多个条件以创建新的分类列
Pandas groupby a column and check multiple conditions to create a new categorical column
与我的查询类似,我正在尝试根据特定的录取石斑鱼代码进行分组,这次在设置类别之前还要检查其他多个条件。
例如,我有以下数据框:
MemberID
AdmittingCode
LOS
Episode
1
a
5
3
2
a
10
6
1
b
2
3
2
b
1
6
现在,我不想简单地检查均值和设置类别,而是要检查均值是否是中值的 2 倍,以及最小集数是否小于 5。我的意思是:
对于 AdmittingCode a,平均值为 7.5 ( (5 + 10) / 2 )。最初,逻辑是将 MemberID 1 的类别设置为 AdmittingCode 作为 a , 0 因为它小于 7.5 LOS(只有 5)和 MemberID 2 with AdmittingCode as a, 1 因为它大于 7.5 LOS(即 10) 使用以下代码:
m = df.groupby('AdmittingCode')['LOS'].transform('mean').lt(df['LOS'])
df['LOSCategory'] = m.astype(int)
但是,现在我想在设置类别列之前再检查 2 个条件。
- 我想检查均值是否不是中位数
的2倍
- 我也想看看集数是否少于5
如果上述两个条件都满足,我希望将类别设置为 0 或 1(即使上述条件仅满足 1 个而其他条件不满足的情况)。
注意:此处的均值和中位数基于每个 AdmittingCode,因此 a 与b 和前面的查询一样。
根据这个逻辑,AdmittingCode a 的平均值为 7.5,中位数也为 7.5,MemberID 1 与 AdmittingCode a 与 LOS 5 和 Episode 计数 3,类别将被设置为 0。这里,平均值是不是中位数的2倍,以及计数,都小于5.
最后观察到如下数据框:
MemberID
AdmittingCode
LOS
Episode
LOSCategory
1
a
5
3
0
2
a
10
6
1
1
b
2
3
0
2
b
1
6
1
您需要编写一个函数 func
来获得 returns 想要的结果。
LOScategory = df.apply(
lambda row: func(row['MemberID'], row['AdmittingCode'],row['LOS'],row['Episode']),
axis=1)
df['LOScategory'] = LOScategory
>>> df['LOSCategory'] = (df.groupby("AdmittingCode")
.apply(lambda x: x.apply(lambda xx:(x.LOS.mean() >= x.LOS.median()*2) | (xx.Episode >= 5), axis=1))
.astype(int)
.to_list()
)
>>> df
MemberID AdmittingCode LOS Episode LOSCategory
0 1 a 5 3 0
1 2 a 10 6 1
2 1 b 2 3 0
3 2 b 1 6 1
与我的查询类似,我正在尝试根据特定的录取石斑鱼代码进行分组,这次在设置类别之前还要检查其他多个条件。
例如,我有以下数据框:
MemberID | AdmittingCode | LOS | Episode |
---|---|---|---|
1 | a | 5 | 3 |
2 | a | 10 | 6 |
1 | b | 2 | 3 |
2 | b | 1 | 6 |
现在,我不想简单地检查均值和设置类别,而是要检查均值是否是中值的 2 倍,以及最小集数是否小于 5。我的意思是:
对于 AdmittingCode a,平均值为 7.5 ( (5 + 10) / 2 )。最初,逻辑是将 MemberID 1 的类别设置为 AdmittingCode 作为 a , 0 因为它小于 7.5 LOS(只有 5)和 MemberID 2 with AdmittingCode as a, 1 因为它大于 7.5 LOS(即 10) 使用以下代码:
m = df.groupby('AdmittingCode')['LOS'].transform('mean').lt(df['LOS'])
df['LOSCategory'] = m.astype(int)
但是,现在我想在设置类别列之前再检查 2 个条件。
- 我想检查均值是否不是中位数 的2倍
- 我也想看看集数是否少于5
如果上述两个条件都满足,我希望将类别设置为 0 或 1(即使上述条件仅满足 1 个而其他条件不满足的情况)。
注意:此处的均值和中位数基于每个 AdmittingCode,因此 a 与b 和前面的查询一样。
根据这个逻辑,AdmittingCode a 的平均值为 7.5,中位数也为 7.5,MemberID 1 与 AdmittingCode a 与 LOS 5 和 Episode 计数 3,类别将被设置为 0。这里,平均值是不是中位数的2倍,以及计数,都小于5.
最后观察到如下数据框:
MemberID | AdmittingCode | LOS | Episode | LOSCategory |
---|---|---|---|---|
1 | a | 5 | 3 | 0 |
2 | a | 10 | 6 | 1 |
1 | b | 2 | 3 | 0 |
2 | b | 1 | 6 | 1 |
您需要编写一个函数 func
来获得 returns 想要的结果。
LOScategory = df.apply(
lambda row: func(row['MemberID'], row['AdmittingCode'],row['LOS'],row['Episode']),
axis=1)
df['LOScategory'] = LOScategory
>>> df['LOSCategory'] = (df.groupby("AdmittingCode")
.apply(lambda x: x.apply(lambda xx:(x.LOS.mean() >= x.LOS.median()*2) | (xx.Episode >= 5), axis=1))
.astype(int)
.to_list()
)
>>> df
MemberID AdmittingCode LOS Episode LOSCategory
0 1 a 5 3 0
1 2 a 10 6 1
2 1 b 2 3 0
3 2 b 1 6 1