У меня есть фрейм данных, как показано ниже. Я хотел бы сгруппировать их на основе subject_id, hadm_id и icustay_id. Как только я сгруппирую его, я хотел бы извлечь предметы, у которых более 60% pc из 1 в столбце «val_bw_80_110». Из приведенного ниже примера мы видим, что subject_id = 38 удовлетворяет этому условию (все значения для val_bw_80_110 = 1, что означает 100%), и я хотел бы извлечь группу, которая принадлежит subject_id = 38. Если бы было только две единицы тогда процент был бы 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'])
Мой ожидаемый результат - это просто фрейм данных, содержащий все предметы, которые удовлетворяют условию 60% единиц в val_bw_80_110. Выходной фрейм данных должен иметь все записи (вместе со столбцами) для subject_id = 38.
Я думаю, как выглядит окончательный DataFrame.
Выходной фрейм данных будет содержать все записи с subject_id = 38, потому что это был единственный subject_id, который превысил ограничение в 60% единиц в val_bw_80_110.
Создайте логический индекс 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
Используйте 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, поэтому возможна фильтрация:
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
Просто пытаюсь понять оба решения. Не могли бы вы сообщить мне, в чем польза от преобразования ('mean') вместо прямого использования mean()?
Можете ли вы помочь мне с этим связанным сообщением? stackoverflow.com/questions/55592014/…
Каков ожидаемый результат?