A row filter looks at one row at a time. Sometimes the rule is about the whole group: keep customers with at least three orders, or drop stations whose average rating is low. filter does that:
df.groupby("customer_id").filter(lambda g: len(g) >= 3)
The function gets each group as a small DataFrame (g) and returns True to keep all its rows or False to drop them all. The result has the original rows and columns, not one row per group.
.all() and .any() inside the function test every row of the group: lambda g: (g["channel"] == "Online").all() keeps customers who only ever ordered online.
The same result can come from a mask with transform, which is faster on big tables: df[df.groupby("customer_id")["order_id"].transform("size") >= 3].