Filtering a panda dataframe in one line I had the following data-cleaning question in an interview test that I struggled on (I've changed the details to anonymise it and protect the company's interview process)


  Given the following dataframe df, return a new series with day as the index, and a single column with the set of meals consumed by everyone who ate that day (i.e, both Alice and Bob on days 1 and 3, but only Alice on day 2). Do not use for loops or list comprehensions, only method chaining and a single lambda function that accepts only a single argument.


df = pd.DataFrame({'day':[1, 2, 3, 1, 3]*3,
                   'person':['Alice', 'Alice', 'Alice', 'Bob', 'Bob']*3,
                   'meal':['breakfast', 'breakfast', 'breakfast', 'breakfast', 'breakfast']+
                          ['lunch', 'brunch', 'brunch', 'lunch', 'lunch']+
                          ['dessert', 'dinner', 'snack', 'beer', 'dessert']
                  })


In other words, the goal is to obtain the following dataframe:

goal = pd.DataFrame({'day':[1, 2, 3], 
                     'meal':[{'breakfast', 'lunch'}, 
                             {'breakfast', 'brunch', 'dinner'},
                             {'breakfast'}]
                    }).set_index('day')


Does anyone know how to do this? Thanks!
The first groupby - counts the number of persons per day per meal

The second groupby - counts the number of unique persons in each day

The inner merge between the 2 - matches the number of persons per day+meal to be equal to the number of persons on that day

We've left with a df that contains day-meal couples in each row, with the number of persons that had a meal which matches the total number of persons on that day:



Now we only need to groupby day and create the set of the meals 

df.groupby(['day','meal']).count().reset_index()\ 
  .merge(df.groupby('day')['person'].apply(lambda x: len(set(x))).reset_index(), 
         on=['day','person'])\ 
  .groupby(['day'])['meal'].apply(set)