Как фильтровать значения во фрейме данных по сгруппированным значениям в столбце

#python #python-3.x #pandas #dataframe

Вопрос:

У меня есть фрейм данных:

 id    value
a1      0
a1      1
a1      2
a1      3
a2      0
a2      1
a3      0
a3      1
a3      2
a3      3
 

Я хочу отфильтровать идентификаторы и оставить только те, значение которых превышает 3. Таким образом, в этом примере идентификатор a2 должен быть удален, так как он имеет только значения 0 и 1. Таким образом, желаемый результат:

 id    value
a1      0
a1      1
a1      2
a1      3
a3      0
a3      1
a3      2
a3      3
a3      4
a3      5
 

Как это сделать в панд?

Комментарии:

1. Должны ли значения быть в порядке? Могут ли быть дубликаты, чтобы [0,2,1,1,3] в «идентификаторе» все равно сохранялось, потому что есть по крайней мере одно из 4 требуемых чисел

2. Последние две строки результата отсутствуют в исходном наборе данных. Это что, ошибка?

3. Я не понимаю, почему вы приняли ответ @DYZ (извините, DYZ), потому что это не ожидаемый результат? В противном случае обновите публикуемые вами правильные данные, чтобы другие люди, у которых есть аналогичная проблема, могли понять.

4. @Corralien Я согласен, мой ответ был неправильным. Вероятно, потому, что вопрос не совсем ясен. Я обновил свой ответ, и он все еще формально неверен, потому что 3 не выше 3. Не стесняйтесь понижать голос, без обид.

5. @DYZ. Вы правы, вопрос неясен, и ОП не дает ответа. К вашему сведению, я никогда не понижаю голос, я предпочитаю обсуждать.

Ответ №1:

Обновленный.

Сгруппируйте по идентификаторам и найдите их максимальные значения. Найдите идентификаторы, максимальное значение которых равно или превышает 3:

 keep = df.groupby('id')['value'].max() >= 3
 

Выберите строки с соответствующими идентификаторами:

 df[df['id'].isin(keep[keep].index)]  
 

Ответ №2:

Используйте логическую маску, чтобы сохранить строки, соответствующие условию, а затем замените bad id (a2) на следующий id (a3). Наконец, снова сгруппируйте по id применяемой совокупной сумме.

 mask = df.groupby('id')['value'] 
         .transform(lambda x: sorted(x.tolist()) == [0, 1, 2, 3])

df1 = df[mask].reindex(df.index).bfill()
df1['value'] = df1.groupby('id').agg('cumcount')
 

Выход:

 >>> df1
   id  value
0  a1      0
1  a1      1
2  a1      2
3  a1      3
4  a3      0
5  a3      1
6  a3      2
7  a3      3
8  a3      4
9  a3      5