我有一个数据框,如下所示。我想根据subject_id,hadm_id和icustay_id对它们进行分组。将其分组后,我想提取“ val_bw_80_110”列中的pc大于1的pc的60%的主题。从下面的示例中,我们可以看到subject_id = 38满足此条件(val_bw_80_110的所有值= 1,表示100%),我想提取属于subject_id = 38的组。如果只有两个1那么百分比应该是66.666等
我已经尝试使用groupby,但是由于不确定如何获取列中的值百分比而无法继续进行操作
data = [[38,10,110,1,0,0], [38,10,110,1,0,0],[38,10,110,1,0,0],
[28,11,120,1,0,0],[28,11,120,0,1,0],[28,11,120,0,0,1],
[48,13,130,1,0,0],[48,13,130,0,1,0],[48,13,130,0,0,1]]
df = pd.DataFrame(data, columns =['subject_id','hadm_id','icustay_id',
'val_bw_80_110','val_lt_80','val_gt_110'])
new_df = df.groupby(['subject_id','hadm_id','icustay_id'])
我的预期结果只是一个数据框,其中包含满足val_bw_80_110中1的60%的条件的所有主题。输出数据框应具有subject_id = 38的所有记录(以及列)
答案 0 :(得分:1)
创建一个满足您条件的subject_id
的布尔索引,然后将Series.isin
与DataFrame.loc
一起使用以对其进行过滤。
s = df.groupby(['subject_id','hadm_id','icustay_id'])['val_bw_80_110'].mean().ge(0.6)
df.loc[df.subject_id.isin(s.index.levels[0][s])]
[输出]
subject_id hadm_id icustay_id val_bw_80_110 val_lt_80 val_gt_110
0 38 10 110 1 0 0
1 38 10 110 1 0 0
2 38 10 110 1 0 0
答案 1 :(得分:1)
将boolean indexing
与GroupBy.transform
一起使用以获取1
值的百分比:
df1 = (df[df.groupby(['subject_id','hadm_id','icustay_id'])['val_bw_80_110']
.transform('mean').ge(0.6)])
print (df1)
subject_id hadm_id icustay_id val_bw_80_110 val_lt_80 val_gt_110
0 38 10 110 1 0 0
1 38 10 110 1 0 0
2 38 10 110 1 0 0
如果使用transform
获得与原始DataFrame相同大小的Series,则可能进行过滤:
print (df.groupby(['subject_id','hadm_id','icustay_id'])['val_bw_80_110']
.transform('mean'))
0 1.000000
1 1.000000
2 1.000000
3 0.333333
4 0.333333
5 0.333333
6 0.333333
7 0.333333
8 0.333333
Name: val_bw_80_110, dtype: float64
print (df.groupby(['subject_id','hadm_id','icustay_id'])['val_bw_80_110']
.transform('mean').ge(0.6))
0 True
1 True
2 True
3 False
4 False
5 False
6 False
7 False
8 False
Name: val_bw_80_110, dtype: bool