How can I count occurrences with groupBy?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Counting occurrences with groupby usually means grouping rows by one or more keys and then asking how many rows fall into each group. In pandas, there are several ways to do that, and the right one depends on whether you want total row counts, non-null counts for a specific column, or counts across multiple grouping keys.
Use size() for Raw Group Counts
If you want the number of rows in each group regardless of null values, size() is the clearest choice.
Output:
size() counts rows, not non-null values in a chosen column.
Use count() When Null Handling Matters
If you group by a key and then call count() on a column, pandas counts only non-null values in that column.
This produces 2 for team B because one player value is null. That difference between size() and count() is one of the most common sources of confusion.
Return a DataFrame Instead of an Index Series
Sometimes you want a normal table rather than a grouped index result. Use reset_index and name the output column.
This is especially useful when the result will be merged with other tables or exported.
Group by Multiple Columns
You can count combinations of several keys the same way.
This answers questions such as "how many times did each region-product pair appear".
When value_counts() Is Simpler
If you only need counts for one column and no other aggregation, value_counts() is often shorter than groupby.
Use groupby when you want a more explicit grouping pipeline or need multiple-key aggregation. Use value_counts() when you only care about one column frequency table.
Sort the Result for Predictable Output
After counting, it is often useful to sort the grouped result before presenting or testing it. That keeps reports and assertions stable even when the input order changes. A sorted summary is easier to compare in notebooks, logs, and regression tests.
Grouped Counts Are Often the Start of a Larger Aggregation
Counting by group is frequently the first step before adding sums, means, or percentages. Writing the counting step clearly now makes it much easier to extend the pipeline later with agg or merges against dimension tables. That is another reason to choose a tidy, named result instead of leaving the counts in an anonymous Series.
Common Pitfalls
- Using
count()when you really want row counts including null values. - Forgetting to call
reset_indexand then wondering why the result is awkward to merge or export. - Reaching for
groupbywhenvalue_counts()would be simpler for a single column. - Counting a column with many missing values and misreading the result as a total row count.
- Grouping by multiple columns without naming the output, which makes the result harder to read later.
Summary
- Use
groupby(...).size()for total row counts per group. - Use
groupby(...)[column].count()when you want non-null counts in a specific column. - Use
reset_index(name=...)if you want a regular tabular result. - Group by multiple columns to count unique key combinations.
- Prefer
value_counts()when you only need one-column frequency counts.

