Hello! Welcome to the first lesson of Module 2.
In the previous module, we focused on sourcing and preparing our data. We concluded by consolidating everything into a single, tidy DataFrame with columns for country, movie_title, date, and some viewing metric (like rank or view count). Our data is now primed for analysis.
Today, we will tackle our first analytical task and address the learning outcome: Aggregate viewing data to determine the most-watched movies for each country. This is the first step in uncovering the movie trends that are central to our project goal.
We will achieve this using one of the most powerful features in the pandas library: the groupby() method. You will learn to implement the "Split-Apply-Combine" strategy, a fundamental pattern in data analysis. Given your background in software engineering, you can think of this as the pandas equivalent of SQL's GROUP BY clause, used for calculating aggregate statistics on data subsets.
Let's get started.
1. The "Split-Apply-Combine" Strategy
Before we write any code, it's crucial to understand the conceptual workflow for aggregation. The "Split-Apply-Combine" strategy consists of three stages:
- Split: We split our large, single DataFrame into smaller groups based on some criteria. For our goal, we will split the data by country. This will give us a separate group of rows for each country in our dataset.
- Apply: We apply a function to each of these smaller groups independently. This function performs a calculation, such as counting occurrences, summing values, or finding the mean. This is the aggregation step.
- Combine: The results of the function applied to each group are combined back into a single DataFrame or Series, giving us a summary view of our data.
This powerful pattern is the key to transforming raw, row-level data into meaningful, high-level insights.
The following video provides an excellent introduction to this concept and the pandas tools we'll be using.
Python Pandas Tutorial (Part 8): Grouping and Aggregating - Analyzing and Exploring Your Data
The video 'Python Pandas Tutorial (Part 8): Grouping and Aggregating' by Corey Schafer clearly explains the 'split-apply-combine' concept and demonstrates how to implement it. It's a foundational skill for any data analysis task.
Please watch the section from 12:50 to 18:21. Focus on how the .groupby() method is used to split the DataFrame into groups and how get_group() allows you to inspect an individual group. This will solidify your understanding of the 'Split' phase.
2. Defining and Calculating "Most-Watched"
The term "most-watched" can be interpreted in several ways, depending on the data you have. For example:
- If you have a
view_hourscolumn, you'd want the movie with the maximum sum of hours. - If you have a
rankcolumn, you might want the movie with the best (lowest) average rank. - If your data is a list of top movies per day, you could define "most-watched" as the movie that appears most frequently in the top list during the pre-Christmas period.
For our project, let's focus on this last definition: the movie that appears most often in a country's data. This is a robust way to measure popularity with the kind of top-list data we've gathered.
To calculate this, we will use the value_counts() method, which you've seen before, but this time we'll apply it to our country groups.
This next segment of the same video demonstrates exactly how to apply an aggregation function like value_counts() to a grouped object.
Python Pandas Tutorial (Part 8): Grouping and Aggregating - Analyzing and Exploring Your Data
Continuing with Corey Schafer's tutorial, this section shows how to perform the 'Apply' and 'Combine' steps to get meaningful statistics for each group.
Please watch the segment from 18:21 to 23:30. Pay close attention to how he applies .value_counts() to the 'social media' column for each country group. This is directly analogous to what we will do with the 'movie_title' column.
3. Finding the Top Movie for Each Country
Following the video's example, we can get the counts of every movie for every country. The code would look something like this:
# Assuming 'df' is our tidy DataFrame from the previous lesson
movie_counts = df.groupby('country')['movie_title'].value_counts()
print(movie_counts)
This will produce a pandas Series with a MultiIndex. It might look like this:
country movie_title
Argentina The Christmas Chronicles 15
Home Alone 12
Die Hard 8
Canada The Grinch 22
Elf 18
Love Actually 11
...
This is great, but our goal is to find the single most-watched movie per country. We need to extract the top entry for each group. A robust and clear way to do this involves a few steps:
- Calculate the size of each group of
(country, movie_title). This is equivalent tovalue_counts(). - Convert the resulting Series to a DataFrame for easier manipulation.
- For each country, find the index of the row with the maximum count.
- Use
.locto select these rows.
Here is the full sequence of operations:
import pandas as pd
# 1. Create a sample DataFrame that mimics our tidy dataset
data = {
'country': ['USA', 'USA', 'USA', 'UK', 'UK', 'USA', 'UK'],
'movie_title': ['Elf', 'Elf', 'Die Hard', 'Love Actually', 'Love Actually', 'Elf', 'The Holiday'],
'date': pd.to_datetime(['2023-12-20', '2023-12-21', '2023-12-21', '2023-12-20', '2023-12-21', '2023-12-22', '2023-12-22'])
}
df = pd.DataFrame(data)
# 2. Group by country and movie, then count the size of each group
# .size() is efficient for this. We then reset the index to turn the MultiIndex Series into a DataFrame.
counts_df = df.groupby(['country', 'movie_title']).size().reset_index(name='appearance_count')
print("--- Counts per Movie ---")
print(counts_df)
# country movie_title appearance_count
# 0 UK Love Actually 2
# 1 UK The Holiday 1
# 2 USA Die Hard 1
# 3 USA Elf 3
# 3. Find the index of the maximum count for each country group
# .idxmax() returns the index of the first occurrence of the maximum value.
idx = counts_df.groupby('country')['appearance_count'].idxmax()
print("\n--- Indices of Top Movies ---")
print(idx)
# country
# UK 0 (Index 0 corresponds to 'Love Actually' for the UK)
# USA 3 (Index 3 corresponds to 'Elf' for the USA)
# Name: appearance_count, dtype: int64
# 4. Use .loc to select the rows with these indices to get our final result
top_movies_per_country = counts_df.loc[idx]
print("\n--- Top Movie per Country ---")
print(top_movies_per_country)
# country movie_title appearance_count
# 0 UK Love Actually 2
# 3 USA Elf 3
This final top_movies_per_country DataFrame is exactly the output we need. It clearly lists the most popular movie for each country, which we can use for visualization in our next lesson. This general groupby().idxmax() pattern is a staple in data analysis for finding the top item per category.
It's also worth noting that this type of aggregation is common in industry and academia. For instance, the paper "Assessing movie-country relatedness" (resource LINK) calculates a "Movie Ubiquity" metric by counting how many top-20 lists a movie appears on globally (see section 'Method'). This is a direct application of the counting and grouping principle we've just used.
Test your understanding!
You have the following DataFrame df_views:
| country | movie_title | rank | |
|---|---|---|---|
| 0 | France | Le Père Noël | 1 |
| 1 | France | Klaus | 2 |
| 2 | Japan | Tokyo Godfathers | 1 |
| 3 | France | Klaus | 1 |
| 4 | Japan | Home Alone | 2 |
| 5 | Japan | Tokyo Godfathers | 1 |
Your task is to produce a DataFrame that shows the most frequently appearing movie for each country. What pandas code would you use?
Show answer
You would use the groupby-size-idxmax pattern we just discussed:
# First, group by country and movie title and get the counts
counts_df = df_views.groupby(['country', 'movie_title']).size().reset_index(name='count')
# Next, find the index of the maximum count within each country group
idx = counts_df.groupby('country')['count'].idxmax()
# Finally, select these rows to get the result
top_movies = counts_df.loc[idx]
print(top_movies)
This would correctly produce the following output:
| country | movie_title | count | |
|---|---|---|---|
| 1 | France | Klaus | 2 |
| 2 | Japan | Tokyo Godfathers | 2 |
Conclusion
In this lesson, you've transitioned from data preparation to data analysis. You learned how to aggregate data to extract meaningful summary statistics—a core task in any data science project.
Key Takeaways:
- Split-Apply-Combine: This three-step strategy (split data into groups, apply a function, combine results) is a universal pattern for data aggregation.
groupby()is Key: Thepandasgroupby()method is your primary tool for implementing this strategy.- Aggregation Functions: You can apply various functions to your groups, such as
sum(),mean(),size(), orvalue_counts(), to calculate the statistic you need. - Finding the Top Item: The pattern of using
groupby().size()followed bygroupby().idxmax()is a powerful and reliable way to find the record with the maximum value within each category.
You now have a new, aggregated dataset that tells a story: which single movie was most popular in each country before Christmas.
In our next lesson, we will bring this story to life. We will design a choropleth map to display the single most popular movie in each country, turning our table of data into a compelling geographical visualization.