Filter dataframe group by not match to set

Viewed 97

Given this dataframe and set:

df = pd.DataFrame({'blah':['cats','cats','dogs','dogs','snakes','snakes','bears','bears'],
                   'foo':['A', 'B', 'B', 'A', 'A', 'B', 'A', 'A']})
   
    blah    foo
0   cats    A
1   cats    B
2   dogs    B
3   dogs    A
4   snakes  A
5   snakes  B
6   bears   A
7   bears   A

letters = set(['A', 'B'])

{'A', 'B'}

I want to filter the dataframe so that it includes only groups of blah where set(foo) does not match letters.

My expected result is:

    blah    foo
6   bears   A
7   bears   A

Below is the closest thing I've got, but I can't figure out how to compare to letters, and I don't want to return a DataFrame and not a Series.

df.groupby('blah')['foo'].apply(set)
2 Answers

This should work:

df.loc[df['blah'].map(df.groupby('blah').agg(set)['foo'].ne(letters))]

This answer checks if the set of values within foo for each group are not equal to the letters set. That is used to index the original data:

>>> mask = df.groupby('blah')['foo'].apply(lambda x: set(x) != letters)
>>> df[df['blah'].map(mask)]

    blah foo
6  bears   A
7  bears   A
Related