Удаление элементов в группах pandas groupby на основе значений - PullRequest
1 голос
/ 05 мая 2020

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

ID     A              B     C
"Z"    "apple"        1     5
"Z"    "pear"         3     1
"C"    "apple"        1     8
"E"    "strawberry"   2     5
"E"    "pear"         5     1
"D"    "apple"        1     5
"D"    "pear"         3     1
"D"    "melon"        1     5

Для тех, у кого одинаковый идентификатор, я хочу отфильтровать строки следующим образом: если есть две записи под одним идентификатором, а одна из них - " яблоко ", я хочу удалить строку, содержащую" яблоко ". Если у меня более двух записей, и одна из них - «яблоко», а также если у меня есть более одной записи для этого идентификатора, и ни одна из них не является «яблоком», я хочу удалить все записи, принадлежащие этому идентификатору. Таким образом, df должен выглядеть так:

ID     A              B     C
"Z"    "pear"         3     1
"C"    "apple"        1     8

Я предполагаю, что отправной точкой должна быть группа по идентификатору, но я не могу понять, как написать функцию, которая сделает все остальное.

1 Ответ

4 голосов
/ 05 мая 2020

Используйте boolean indexing с маской | для побитового OR:

#filter apples
m0 = df['A'].eq('apple')
#get counts per groups
s = df.groupby('ID')['ID'].transform('size')
#check if at least one apple per group
m2 = m0.groupby(df['ID']).transform('any')

#chain mask with length 2, at least one apple and all not apples OR 
#length 1 with apples
df = df[(s.eq(2) & ~m0 & m2) | (s.eq(1) & m0)]
print (df)
  ID      A  B  C
1  Z   pear  3  1
2  C  apple  1  8

Подробности :

with pd.option_context('expand_frame_repr', False):

    print (df.assign(m = m0, 
                     s = s,
                     m2 = m2,
                     s2 = s.eq(2),
                     invm0 = ~m0,
                     first = (s.eq(2) & ~m0 & m2),
                     s1 = s.eq(1),
                     second = (s.eq(1) & m0),
                     both =(s.eq(2) & ~m0 & m2) | (s.eq(1) & m0)
           ))
  ID           A  B  C      m  s     m2     s2  invm0  first     s1  second   both
0  Z       apple  1  5   True  2   True   True  False  False  False   False  False
1  Z        pear  3  1  False  2   True   True   True   True  False   False   True
2  C       apple  1  8   True  1   True  False  False  False   True    True   True
3  E  strawberry  2  5  False  2  False   True   True  False  False   False  False
4  E        pear  5  1  False  2  False   True   True  False  False   False  False
5  D       apple  1  5   True  3   True  False  False  False  False   False  False
6  D        pear  3  1  False  3   True  False   True  False  False   False  False
7  D       melon  1  5  False  3   True  False   True  False  False   False  False
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...