What’s New ?

The Top 10 favtutor Features You Might Have Overlooked

Read More
Computer Science

Pandas Groupby Count with Examples (count vs size)

Jul 18, 2026 4 Minutes Read Why Trust Us Why you can trust this guide. Written by working engineers and reviewed by our editorial team under a strict editorial policy for accuracy, clarity and zero bias. Shivali Bhadaniya By Shivali Bhadaniya Shivali Bhadaniya Shivali Bhadaniya
I'm Shivali Bhadaniya, a computer engineer student and technical content writer, very enthusiastic to learn and explore new technologies and looking towards great opportunities. It is amazing for me to share my knowledge through my content to help curious minds.
Connect on LinkedIn →
Pandas Groupby Count with Examples (count vs size)

In pandas, the standard way to count rows per group is df.groupby("column").size(). The related count() method also counts per group, but it skips missing values and counts each column separately.

Which one you want depends on the question: "how many rows are in each group" is a size() question, and "how many non-null values does each column have per group" is a count() question.

How Do You Count Rows per Group in Pandas?

Group the DataFrame by a column and call size(). The result is a Series with one row count per group:

import pandas as pd

df = pd.DataFrame({
    "city": ["delhi", "mumbai", "delhi", "goa", "delhi"],
    "order_id": [101, 102, 103, 104, 105],
})

print(df.groupby("city").size())
# Outputs:
# city
# delhi     3
# goa       1
# mumbai    1
# dtype: int64
Rows being split into city groups and each group being counted, showing how groupby size works

5 Ways to Count with Pandas Groupby

1) groupby().size()

size() counts every row in each group, including rows with missing values, and returns one number per group:

print(df.groupby("city").size())
# Outputs:
# city
# delhi     3
# goa       1
# mumbai    1
# dtype: int64

2) groupby().count()

count() counts the non-null values of every other column, group by group, and returns a DataFrame with one column per counted column:

print(df.groupby("city").count())
# Outputs:
#         order_id
# city
# delhi          3
# goa            1
# mumbai         1

3) value_counts()

When all you need is how often each value appears in one column, value_counts() does the group-and-count in a single call and sorts the result largest first:

print(df["city"].value_counts())
# Outputs:
# city
# delhi     3
# mumbai    1
# goa       1
# Name: count, dtype: int64

4) groupby().agg()

agg() counts as part of a larger aggregation, and named aggregation lets you name the output column at the same time:

result = df.groupby("city").agg(orders=("order_id", "count"))
print(result)
# Outputs:
#         orders
# city
# delhi        3
# goa          1
# mumbai       1

5) groupby().transform()

transform("count") returns the group count aligned to every original row, which is how you add a count column to the DataFrame without collapsing it:

df["city_orders"] = df.groupby("city")["order_id"].transform("count")
print(df)
# Outputs:
#      city  order_id  city_orders
# 0   delhi       101            3
# 1  mumbai       102            1
# 2   delhi       103            3
# 3     goa       104            1
# 4   delhi       105            3

Pandas Groupby Count vs Size

The two methods disagree the moment a group contains missing values. size() counts rows, count() counts non-null values:

import pandas as pd
import numpy as np

df = pd.DataFrame({
    "city": ["delhi", "delhi", "mumbai"],
    "rating": [4.5, np.nan, 4.0],
})

print(df.groupby("city").size())
# Outputs:
# city
# delhi     2
# mumbai    1
# dtype: int64

print(df.groupby("city")["rating"].count())
# Outputs:
# city
# delhi     1
# mumbai    1
# Name: rating, dtype: int64

Delhi has two rows but only one rating, so size() says 2 and count() says 1. The other differences:

size()count()
Missing values (NaN)IncludedExcluded
Return typeSeries, one number per groupDataFrame, one column per counted column
Question it answersHow many rows per groupHow many non-null values per column per group

Naming the Count Column

size() returns a Series with the group labels in the index. reset_index(name="count") turns it into a tidy DataFrame with a named column, which is the usual shape for further processing or plotting:

counts = df.groupby("city").size().reset_index(name="count")
print(counts)
# Outputs:
#      city  count
# 0   delhi      2
# 1  mumbai      1

Examples of Counting with Groupby

1) Counting Orders per City, Sorted

Chaining sort_values() ranks the groups by their count:

import pandas as pd

orders = pd.DataFrame({
    "city": ["delhi", "mumbai", "delhi", "goa", "delhi", "mumbai"],
    "amount": [250, 480, 120, 900, 330, 610],
})

top = orders.groupby("city").size().sort_values(ascending=False)
print(top)
# Outputs:
# city
# delhi     3
# mumbai    2
# goa       1
# dtype: int64

2) Counting Unique Values per Group

nunique() counts distinct values instead of all values, such as how many different cities each customer ordered from:

import pandas as pd

orders = pd.DataFrame({
    "customer": ["riya", "riya", "sam", "riya"],
    "city": ["delhi", "delhi", "mumbai", "goa"],
})

print(orders.groupby("customer")["city"].nunique())
# Outputs:
# customer
# riya    2
# sam     1
# Name: city, dtype: int64

Learn More About Counting in Pandas

Counting All Rows in a DataFrame

Without grouping, len(df) returns the total row count, and df.shape returns rows and columns together. df.count() without a groupby gives per-column non-null counts, following the same NaN rule as its groupby version:

print(len(orders))    # Outputs: 4
print(orders.shape)   # Outputs: (4, 2)

Counting Multiple Group Keys

Passing a list of columns groups by their combinations, which counts each pair once per occurrence:

print(orders.groupby(["customer", "city"]).size())
# Outputs:
# customer  city
# riya      delhi     2
#           goa       1
# sam       mumbai    1
# dtype: int64

Key Takeaways for Pandas Groupby Count

  • Rows per group is size() - It counts every row, including rows with missing values.
  • Non-null values is count() - It skips NaN and reports each column separately.
  • One column's frequencies is value_counts() - Group, count, and sort in a single call.
  • Name the output - size().reset_index(name="count") gives a tidy DataFrame.
  • Keep every row - transform("count") aligns the counts back onto the original DataFrame.
  • Distinct values is nunique() - Use it when duplicates should count once.

Counting how many values fall in each group usually leads to asking which values they are. The pandas unique values lesson covers exactly that.

Shivali Bhadaniya
About the author

Shivali Bhadaniya

I'm Shivali Bhadaniya, a computer engineer student and technical content writer, very enthusiastic to learn and explore new technologies and looking towards great opportunities. It is amazing for me to share my knowledge through my content to help curious minds. Connect on LinkedIn →