Analyze Netflix Data with Python
Clean and explore 8,000+ Netflix titles to uncover content trends.
Introduction
30 Second Summary
Netflix has thousands of movies and TV shows in its library. Have you ever wondered which countries produce the most content, or whether Netflix is adding more TV shows over time? The answers are hidden inside a dataset, waiting to be uncovered.
In this project, you will analyze a real Netflix dataset using Python. You will clean messy data, uncover trends about content production, and build professional visualizations that tell a story.
What You'll Build
You will perform a complete exploratory data analysis on the Netflix Movies and TV Shows dataset using pandas and matplotlib in Google Colab.
By the end of this project, you'll have:
- A cleaned DataFrame with 8,000+ Netflix titles, free of missing values and ready for analysis.
- Data-driven insights about Netflix content trends, including top countries, content type shifts, and genre distribution.
- Professional bar chart visualizations built with matplotlib that communicate your findings clearly.
- Secret Mission: a content recommender function that filters Netflix titles by genre, country, and year range.
Are there any prerequisites?
None. This guide includes setup for all required tools. Google Colab runs in your browser and comes with Python, pandas, and matplotlib pre-installed.
Before We Start
Before We Start...
Set Up Google Colab and Load the Dataset
Every data analysis project starts with two things: a tool to write code in and a dataset to explore.
Google Colab is a free, browser-based notebook environment where you can write and run Python without installing anything on your computer. In this step, you will open Colab, load the Netflix dataset, and inspect its structure.
In this step, get ready to:
- Open Google Colab and create a new notebook.
- Load the Netflix dataset into a pandas DataFrame.
- Inspect the dataset's shape, columns, and data types.
Open Google Colab and create a new notebook
Google Colab comes with pandas, matplotlib, and other data science libraries pre-installed. No setup required beyond a Google account.
- Open your browser and navigate to colab.research.google.com.
- Sign in with your Google account if prompted.
- Click New Notebook in the bottom-right corner of the pop-up window.
A new untitled notebook opens with an empty code cell ready for you to type in.
What is Google Colab?
Google Colab is a free cloud-based Jupyter notebook environment. It runs Python in your browser with no installation needed.
You write code in "cells" and run each cell individually. Output appears directly below the cell you ran.
Don't see the New Notebook button?
If the pop-up window did not appear, click File in the top-left menu bar, then select New notebook.
Make sure you are signed into a Google account. Colab requires one to create and save notebooks.
help me open a new notebook in Google Colab
Import libraries and load the Netflix dataset
Before you can analyze data, you need to import the libraries that make analysis possible. Then you will pull the Netflix dataset directly from a public URL into a DataFrame.
- Type the following code into the first code cell of your notebook:
# Cell 1: Import libraries and load data
import pandas as pd
import matplotlib.pyplot as plt
# Download the Netflix dataset
url = "https://raw.githubusercontent.com/DataScienceRoadMapDSRM/Movie-Recommendation-System/master/Dataset/netflix_titles.csv"
df = pd.read_csv(url)
What does this code do?
- import pandas as pd loads the pandas library for working with tabular data. The pd shorthand lets you call pandas functions without typing the full name.
- import matplotlib.pyplot as plt loads the plotting library you will use later to create charts.
- pd.read_csv(url) downloads the CSV file from the URL and loads it into a DataFrame called df. A DataFrame is like a spreadsheet in Python.
You will not see any output yet. The next section adds print statements to inspect what you loaded.
Inspect the dataset
Now that the data is loaded, you need to understand what you are working with. How many rows and columns are there? What types of data does each column hold?
- Add the following lines below your existing code in the same cell:
print(f"Shape: {df.shape}")
print(f"Columns: {df.columns.tolist()}")
print(f"\nData types:\n{df.dtypes}")
df.head()
What does this code do?
- df.shape returns the number of rows and columns as a tuple.
- df.columns.tolist() prints all column names so you know what data fields are available.
- df.dtypes shows the data type of each column (text, numbers, or dates).
- df.head() displays the first 5 rows of data as a formatted table.
- Run the cell by pressing Shift+Enter on your keyboard, or by clicking the play button on the left side of the cell.
You should see output showing the dataset has approximately 8,800 rows and 12 columns. The columns include show_id, type, title, director, cast, country, date_added, release_year, rating, duration, listed_in, and description.
Seeing a ConnectionError or timeout?
This means Colab could not reach the dataset URL. Check that you copied the URL string exactly, including the full path. Make sure you have an active internet connection.
If you see a NameError: name 'df' is not defined, make sure all your code is in the same cell and you ran the entire cell (not just part of it).
help me fix an error loading a CSV in Google Colab with pandas
✔️ Awesome, I've got everything!
Great. Double check you have both the imports and the print statements in your cell, then move on to the next step.
ⓧ I'd like to double check the full code
Here is the complete Cell 1 code. Make sure your cell matches this exactly.
# Cell 1: Import libraries and load data
import pandas as pd
import matplotlib.pyplot as plt
# Download the Netflix dataset
url = "https://raw.githubusercontent.com/DataScienceRoadMapDSRM/Movie-Recommendation-System/master/Dataset/netflix_titles.csv"
df = pd.read_csv(url)
print(f"Shape: {df.shape}")
print(f"Columns: {df.columns.tolist()}")
print(f"\nData types:\n{df.dtypes}")
df.head()
Your data is loaded and you know its shape. Next up, you will clean up the missing values and messy formatting so the dataset is ready for real analysis.
Explore and Clean the Data
You've loaded the Netflix dataset and inspected its structure. Before you can analyze trends, you need to deal with messy data.
Real-world datasets almost always have missing values and inconsistent formatting. In this step, you'll find the gaps, fill them with sensible defaults, and create new columns that make analysis easier.
In this step, get ready to:
- Check for missing values and calculate their percentages.
- Clean missing data by filling gaps with "Unknown" and converting dates.
- Extract primary countries and verify the cleaned DataFrame.
Check for missing values
Every data analysis starts with understanding what's missing. Gaps in your data can skew results and crash your code if you don't handle them.
- Click the + Code button at the top of your Colab notebook to create a new code cell below your existing one.
- Check how much data is missing per column by pasting this code into the new cell:
# Cell 2: Check for missing values
print("Missing values per column:")
print(df.isnull().sum().sort_values(ascending=False))
print(f"\nMissing value percentages:")
print((df.isnull().sum() / len(df) * 100).sort_values(ascending=False).round(1))
What does this code do?
`df.isnull().sum()` counts how many null values exist in each column. Sorting by descending order puts the most problematic columns at the top.
The percentage calculation divides each column's null count by the total number of rows. This tells you the severity of the gaps at a glance.
- Run the cell by pressing Shift+Enter.
- You should see a list of columns with their missing value counts. The director column has the most missing values (around 30%), followed by cast and country at around 10% each.
Seeing a NameError?
If you see NameError: name 'df' is not defined, your Cell 1 hasn't been run yet. Go back to your first cell and press Shift+Enter to execute it first. Colab cells must run in order.
Help me fix this NameError
Clean missing values and convert dates
Now that you know where the gaps are, you'll fill them. For text columns like director and cast, replacing nulls with "Unknown" keeps those rows usable without inventing fake data.
- Create a new code cell by clicking + Code.
- Fill the missing values and convert the date column by pasting this code:
# Cell 3: Clean the data
df["director"] = df["director"].fillna("Unknown")
df["cast"] = df["cast"].fillna("Unknown")
df["country"] = df["country"].fillna("Unknown")
df["date_added"] = pd.to_datetime(df["date_added"].str.strip(), errors="coerce")
df["year_added"] = df["date_added"].dt.year
What does this code do?
`fillna("Unknown")` replaces every null value in the column with the string "Unknown". This keeps your rows intact for analysis without pretending to know the actual director or cast.
`pd.to_datetime()` converts the date_added text into actual date objects. The .str.strip() removes leading whitespace that exists in some entries, and errors="coerce" turns unparseable dates into nulls instead of crashing.
`dt.year` extracts just the year from the date, creating a new column that's easier to group by when you analyze trends.
- Don't run this cell yet. You'll add more code to it in the next substep.
Extract the primary country and verify your cleaning
The country column lists multiple countries separated by commas for co-productions. To count which countries produce the most content, you need just the first (primary) country from each entry.
- In the same Cell 3, add this code below the year_added line:
df["country_primary"] = df["country"].apply(
lambda x: x.split(",")[0].strip() if x != "Unknown" else "Unknown"
)
print("After cleaning - remaining nulls in key columns:")
print(df[["director", "cast", "country", "date_added", "year_added"]].isnull().sum())
print(f"\nCleaned shape: {df.shape}")
What does this code do?
The lambda function takes each country value and splits it at the first comma to grab only the primary country. If the value is "Unknown" (from your earlier fill), it stays as "Unknown" instead of trying to split it.
The final print statements verify your cleaning worked. You should see zero nulls in director, cast, and country. The date_added and year_added columns may still show a few nulls from unparseable dates.
- Run the full Cell 3 by pressing Shift+Enter.
- You should see director, cast, and country all showing 0 missing values. The cleaned shape should still show 8,000+ rows, confirming you haven't lost any data.
Seeing unexpected nulls in director or country?
If director or country still shows nulls, make sure your fillna lines come before the date_added conversion. Order matters in the cell.
Also check that you typed "Unknown" with a capital U. Python is case-sensitive, so "unknown" would not match later when the country_primary lambda checks if x != "Unknown".
Help me debug my cleaning code
✔️ Awesome, I've got everything!
Great. Double check you've run both Cell 2 and Cell 3 successfully before moving on.
ⓧ I'd like to double check the full code
Here is the complete notebook code up to this point:
# Cell 1: Import libraries and load data
import pandas as pd
import matplotlib.pyplot as plt
# Download the Netflix dataset
url = "https://raw.githubusercontent.com/DataScienceRoadMapDSRM/Movie-Recommendation-System/master/Dataset/netflix_titles.csv"
df = pd.read_csv(url)
print(f"Shape: {df.shape}")
print(f"Columns: {df.columns.tolist()}")
print(f"\nData types:\n{df.dtypes}")
df.head()
# Cell 2: Check for missing values
print("Missing values per column:")
print(df.isnull().sum().sort_values(ascending=False))
print(f"\nMissing value percentages:")
print((df.isnull().sum() / len(df) * 100).sort_values(ascending=False).round(1))
# Cell 3: Clean the data
df["director"] = df["director"].fillna("Unknown")
df["cast"] = df["cast"].fillna("Unknown")
df["country"] = df["country"].fillna("Unknown")
df["date_added"] = pd.to_datetime(df["date_added"].str.strip(), errors="coerce")
df["year_added"] = df["date_added"].dt.year
df["country_primary"] = df["country"].apply(
lambda x: x.split(",")[0].strip() if x != "Unknown" else "Unknown"
)
print("After cleaning - remaining nulls in key columns:")
print(df[["director", "cast", "country", "date_added", "year_added"]].isnull().sum())
print(f"\nCleaned shape: {df.shape}")
Your data is clean and ready for analysis. Next up, you'll start asking real questions. Which countries produce the most Netflix content? Are Movies or TV Shows growing faster? Time to find out.
Analyze Content Trends
Your data is cleaned and ready to answer real questions. Now comes the most exciting part of any data analysis project: digging into the data to uncover patterns and trends.
In this step, you will use pandas aggregation methods to explore how Netflix's content library breaks down by type, country, and genre.
In this step, get ready to:
- Analyze the Movies vs TV Shows split and how it has changed over time.
- Identify the top 10 content-producing countries.
- Explore the most common genres across all Netflix titles.
Count Movies vs TV Shows
The most basic question about any content library is: what type of content dominates? Netflix offers both Movies and TV Shows, and understanding the split tells you a lot about the platform's strategy.
- Create a new code cell in your notebook and add the following code to count content types and track how the mix changes over time:
# Cell 4: Analyze Movies vs TV Shows
type_counts = df["type"].value_counts()
print("Content type distribution:")
print(type_counts)
print(f"\nMovies: {type_counts.get('Movie', 0) / len(df) * 100:.1f}%")
print(f"TV Shows: {type_counts.get('TV Show', 0) / len(df) * 100:.1f}%")
yearly_type = df.groupby(["year_added", "type"]).size().unstack(fill_value=0)
print("\nContent added per year by type:")
print(yearly_type.tail(10))
What does this code do?
The first half uses value_counts() to count how many Movies and TV Shows exist in the dataset. It then calculates the percentage split so you can see the ratio at a glance.
The second half uses groupby() to group records by both year and content type, then unstack() pivots the result into a table with years as rows and Movie/TV Show as columns. The tail(10) shows only the most recent 10 years.
- Run the cell by pressing the play button or pressing Shift+Enter.
- You should see a count showing Movies outnumber TV Shows (roughly 70% Movies to 30% TV Shows), followed by a table showing how many of each type were added per year.
Seeing a KeyError?
Make sure you ran all previous cells first. The type column comes from the original dataset, so if df is not loaded, this cell will fail.
help me fix a KeyError in my pandas analysis
Find the top content-producing countries
Netflix is a global platform, but some countries contribute far more content than others. Your cleaned country_primary column makes it easy to answer which countries dominate.
- Create a new code cell and add the following code to find the top 10 countries and compare their Movie vs TV Show contributions:
# Cell 5: Top 10 content-producing countries
top_countries = df["country_primary"].value_counts().head(10)
print("Top 10 content-producing countries:")
print(top_countries)
country_type = df[df["country_primary"].isin(top_countries.index)].groupby(
["country_primary", "type"]
).size().unstack(fill_value=0)
print("\nMovies vs TV Shows by top countries:")
print(country_type.sort_values("Movie", ascending=False))
What does this code do?
First, value_counts().head(10) counts how many titles each country produced and keeps only the top 10.
Then the code filters the DataFrame to only rows from those top 10 countries using isin(). It groups by country and type, unstacks the result into a readable table, and sorts by Movie count so you can see which countries are most Movie-heavy.
- Run the cell.
- You should see the United States at the top of the list with the most titles by far, followed by India and the United Kingdom.
Seeing 'Unknown' as a top country?
If "Unknown" appears in your top 10, that means the cleaning step filled many missing country values. This is expected behavior and reflects real gaps in the dataset. The analysis still works correctly.
help me understand why Unknown appears in my country analysis
Explore genre distribution
Each Netflix title can belong to multiple genres. The listed_in column stores these as comma-separated strings like "Documentaries, International Movies". To count individual genres, you need to split each string and count each genre separately.
- Create a new code cell and add the following code to split genres and count the most common ones:
# Cell 6: Genre analysis
all_genres = df["listed_in"].str.split(", ").explode()
genre_counts = all_genres.value_counts().head(15)
print("Top 15 genres:")
print(genre_counts)
What does this code do?
The .str.split(", ") method splits each comma-separated genre string into a list. Then .explode() transforms each list item into its own row. A single title with 3 genres becomes 3 rows, one per genre.
Finally, value_counts().head(15) counts how often each genre appears and shows the top 15. This reveals what types of content Netflix has prioritized.
- Run the cell.
- You should see "International Movies", "Dramas", and "Comedies" near the top of the list. This reflects Netflix's heavy investment in global content.
Getting an AttributeError on str.split?
This can happen if the listed_in column has null values. Check for nulls by running df["listed_in"].isnull().sum() in a separate cell. If you find any, fill them first with df["listed_in"] = df["listed_in"].fillna("").
help me fix an AttributeError in my genre analysis
✔️ Awesome, I've got everything!
Great. Double check you have all three analysis cells saved in your notebook.
ⓧ I'd like to double check the full code
Here is the full notebook code up to this point:
# Cell 1: Import libraries and load data
import pandas as pd
import matplotlib.pyplot as plt
# Download the Netflix dataset
url = "https://raw.githubusercontent.com/DataScienceRoadMapDSRM/Movie-Recommendation-System/master/Dataset/netflix_titles.csv"
df = pd.read_csv(url)
print(f"Shape: {df.shape}")
print(f"Columns: {df.columns.tolist()}")
print(f"\nData types:\n{df.dtypes}")
df.head()
# Cell 2: Check for missing values
print("Missing values per column:")
print(df.isnull().sum().sort_values(ascending=False))
print(f"\nMissing value percentages:")
print((df.isnull().sum() / len(df) * 100).sort_values(ascending=False).round(1))
# Cell 3: Clean the data
df["director"] = df["director"].fillna("Unknown")
df["cast"] = df["cast"].fillna("Unknown")
df["country"] = df["country"].fillna("Unknown")
df["date_added"] = pd.to_datetime(df["date_added"].str.strip(), errors="coerce")
df["year_added"] = df["date_added"].dt.year
df["country_primary"] = df["country"].apply(
lambda x: x.split(",")[0].strip() if x != "Unknown" else "Unknown"
)
print("After cleaning - remaining nulls in key columns:")
print(df[["director", "cast", "country", "date_added", "year_added"]].isnull().sum())
print(f"\nCleaned shape: {df.shape}")
# Cell 4: Analyze Movies vs TV Shows
type_counts = df["type"].value_counts()
print("Content type distribution:")
print(type_counts)
print(f"\nMovies: {type_counts.get('Movie', 0) / len(df) * 100:.1f}%")
print(f"TV Shows: {type_counts.get('TV Show', 0) / len(df) * 100:.1f}%")
yearly_type = df.groupby(["year_added", "type"]).size().unstack(fill_value=0)
print("\nContent added per year by type:")
print(yearly_type.tail(10))
# Cell 5: Top 10 content-producing countries
top_countries = df["country_primary"].value_counts().head(10)
print("Top 10 content-producing countries:")
print(top_countries)
country_type = df[df["country_primary"].isin(top_countries.index)].groupby(
["country_primary", "type"]
).size().unstack(fill_value=0)
print("\nMovies vs TV Shows by top countries:")
print(country_type.sort_values("Movie", ascending=False))
# Cell 6: Genre analysis
all_genres = df["listed_in"].str.split(", ").explode()
genre_counts = all_genres.value_counts().head(15)
print("Top 15 genres:")
print(genre_counts)
You now have concrete, data-driven answers about Netflix's content strategy. Next up, you will turn these numbers into professional visualizations that communicate your findings at a glance.
Visualize Your Findings
In the previous step, you uncovered some powerful insights. Movies dominate Netflix's library, the United States leads content production, and International Movies top the genre list.
Numbers in a table are informative, but a chart tells the story instantly. In this step, you will use matplotlib to create professional bar charts that make your findings visual and shareable.
In this step, get ready to:
- Create a bar chart showing Movies vs TV Shows added per year.
- Build a horizontal bar chart of the top 10 content-producing countries.
- Write a summary of your 3 key findings in a markdown cell.
Create a bar chart of content added per year
Your yearly_type variable already holds the data grouped by year and content type. Now you will turn that into a visual bar chart that makes the trend obvious at a glance.
- Create a new code cell below your genre analysis cell.
- Add the following visualization code:
# Cell 7: Visualization - Content added per year
fig, ax = plt.subplots(figsize=(12, 6))
yearly_type_filtered = yearly_type[yearly_type.index >= 2010]
yearly_type_filtered.plot(kind="bar", ax=ax, color=["#E50914", "#221F1F"], width=0.8)
ax.set_title("Netflix Content Added Per Year (Movies vs TV Shows)", fontsize=14)
ax.set_xlabel("Year Added", fontsize=12)
ax.set_ylabel("Number of Titles", fontsize=12)
ax.legend(title="Type", fontsize=11)
ax.set_xticklabels(ax.get_xticklabels(), rotation=45)
plt.tight_layout()
plt.show()
What does this code do?
This code creates a grouped bar chart comparing Movies and TV Shows added each year.
- plt.subplots(figsize=(12, 6)) creates a figure that is 12 inches wide and 6 inches tall.
- yearly_type[yearly_type.index >= 2010] filters to only show data from 2010 onwards, keeping the chart readable.
- The colors #E50914 (Netflix red) and #221F1F (dark grey) give the chart a Netflix-branded look.
- plt.tight_layout() prevents labels from being cut off at the edges.
- Run the cell by pressing the play button or Shift+Enter.
- You should see a bar chart rendered directly below the cell with red and dark bars for each year from 2010 onwards.
Don't see a chart?
- Make sure you ran all previous cells first. The yearly_type variable must exist before this cell can use it.
- Check that plt.show() is the last line in the cell. Colab renders the chart when it hits this command.
- If you see a blank plot, verify that yearly_type_filtered is not empty by printing it before the plot call.
Help me debug my matplotlib bar chart in Google Colab.
Build a horizontal bar chart of top countries
A horizontal bar chart works well for country names because the labels are easier to read when they run along the y-axis instead of being crammed under vertical bars.
- Create a new code cell below your yearly chart.
- Add the following code to build a horizontal bar chart of the top 10 countries:
# Cell 8: Visualization - Top 10 countries
fig, ax = plt.subplots(figsize=(10, 6))
top_countries.sort_values().plot(kind="barh", ax=ax, color="#E50914")
ax.set_title("Top 10 Content-Producing Countries on Netflix", fontsize=14)
ax.set_xlabel("Number of Titles", fontsize=12)
ax.set_ylabel("Country", fontsize=12)
plt.tight_layout()
plt.show()
What does this code do?
- top_countries.sort_values() sorts the countries from fewest to most titles. This puts the longest bar (United States) at the top of the chart for visual emphasis.
- kind="barh" tells pandas to plot horizontal bars instead of vertical ones.
- The single Netflix red color (#E50914) keeps the chart clean since there is only one data series here.
- Run the cell.
- You should see a horizontal bar chart with country names on the left and red bars extending to the right, with the United States having the longest bar.
Chart looks squished or labels are cut off?
- Make sure plt.tight_layout() is included before plt.show(). This adjusts spacing so labels fit within the figure.
- If the chart is too small, increase the figsize values (the first number is width, the second is height).
Help me fix my horizontal bar chart layout.
Add a summary of your key findings
Every data analysis ends with a conclusion. The numbers and charts you created tell a story, and a summary cell makes that story explicit for anyone reading your notebook.
- Click the + Text button in the toolbar to create a new Markdown cell below your country chart.
- Type the following summary into the Markdown cell:
## Key Findings
1. Netflix's library is dominated by Movies (~70%) over TV Shows (~30%),
but TV Show additions have been growing faster in recent years.
2. The United States is by far the largest content producer, followed by
India and the United Kingdom.
3. International Movies, Dramas, and Comedies are the most common genres,
reflecting Netflix's push toward global content diversity.
Why write a summary?
A data analysis notebook without a conclusion is like a story without an ending. The summary tells your reader what the data means so they do not have to interpret the charts on their own.
In professional settings, stakeholders often skip straight to the conclusion. Clear findings make your analysis actionable.
- Run the Markdown cell by pressing Shift+Enter.
- You should see your findings rendered as formatted text with a bold heading and numbered list.
✔️ Awesome, I've got everything!
Great. Double check you have all three new cells in your notebook (two chart cells and one markdown summary).
ⓧ I'd like to double check the full code
Here is the full notebook code up to this point. Compare it with your cells to make sure everything matches.
# Cell 1: Import libraries and load data
import pandas as pd
import matplotlib.pyplot as plt
# Download the Netflix dataset
url = "https://raw.githubusercontent.com/DataScienceRoadMapDSRM/Movie-Recommendation-System/master/Dataset/netflix_titles.csv"
df = pd.read_csv(url)
print(f"Shape: {df.shape}")
print(f"Columns: {df.columns.tolist()}")
print(f"\nData types:\n{df.dtypes}")
df.head()
# Cell 2: Check for missing values
print("Missing values per column:")
print(df.isnull().sum().sort_values(ascending=False))
print(f"\nMissing value percentages:")
print((df.isnull().sum() / len(df) * 100).sort_values(ascending=False).round(1))
# Cell 3: Clean the data
df["director"] = df["director"].fillna("Unknown")
df["cast"] = df["cast"].fillna("Unknown")
df["country"] = df["country"].fillna("Unknown")
df["date_added"] = pd.to_datetime(df["date_added"].str.strip(), errors="coerce")
df["year_added"] = df["date_added"].dt.year
df["country_primary"] = df["country"].apply(
lambda x: x.split(",")[0].strip() if x != "Unknown" else "Unknown"
)
print("After cleaning - remaining nulls in key columns:")
print(df[["director", "cast", "country", "date_added", "year_added"]].isnull().sum())
print(f"\nCleaned shape: {df.shape}")
# Cell 4: Analyze Movies vs TV Shows
type_counts = df["type"].value_counts()
print("Content type distribution:")
print(type_counts)
print(f"\nMovies: {type_counts.get('Movie', 0) / len(df) * 100:.1f}%")
print(f"TV Shows: {type_counts.get('TV Show', 0) / len(df) * 100:.1f}%")
yearly_type = df.groupby(["year_added", "type"]).size().unstack(fill_value=0)
print("\nContent added per year by type:")
print(yearly_type.tail(10))
# Cell 5: Top 10 content-producing countries
top_countries = df["country_primary"].value_counts().head(10)
print("Top 10 content-producing countries:")
print(top_countries)
country_type = df[df["country_primary"].isin(top_countries.index)].groupby(
["country_primary", "type"]
).size().unstack(fill_value=0)
print("\nMovies vs TV Shows by top countries:")
print(country_type.sort_values("Movie", ascending=False))
# Cell 6: Genre analysis
all_genres = df["listed_in"].str.split(", ").explode()
genre_counts = all_genres.value_counts().head(15)
print("Top 15 genres:")
print(genre_counts)
# Cell 7: Visualization - Content added per year
fig, ax = plt.subplots(figsize=(12, 6))
yearly_type_filtered = yearly_type[yearly_type.index >= 2010]
yearly_type_filtered.plot(kind="bar", ax=ax, color=["#E50914", "#221F1F"], width=0.8)
ax.set_title("Netflix Content Added Per Year (Movies vs TV Shows)", fontsize=14)
ax.set_xlabel("Year Added", fontsize=12)
ax.set_ylabel("Number of Titles", fontsize=12)
ax.legend(title="Type", fontsize=11)
ax.set_xticklabels(ax.get_xticklabels(), rotation=45)
plt.tight_layout()
plt.show()
# Cell 8: Visualization - Top 10 countries
fig, ax = plt.subplots(figsize=(10, 6))
top_countries.sort_values().plot(kind="barh", ax=ax, color="#E50914")
ax.set_title("Top 10 Content-Producing Countries on Netflix", fontsize=14)
ax.set_xlabel("Number of Titles", fontsize=12)
ax.set_ylabel("Country", fontsize=12)
plt.tight_layout()
plt.show()
# Cell 9: Summary markdown (written as comments for reference)
# KEY FINDINGS:
# 1. Netflix's library is dominated by Movies (~70%) over TV Shows (~30%),
# but TV Show additions have been growing faster in recent years.
# 2. The United States is by far the largest content producer, followed by
# India and the United Kingdom.
# 3. International Movies, Dramas, and Comedies are the most common genres,
# reflecting Netflix's push toward global content diversity.
Secret mission
Build a Content Recommender
You have a cleaned dataset and visualizations. But what if you could turn this notebook into a tool that helps someone find their next show? Build a recommender function that filters Netflix titles by genre, country, and year range.
Clean Up Your Resources
Clean Up Your Resources
This project runs entirely in Google Colab for free, so there are no ongoing costs. Your notebook is saved to your Google Drive automatically.
Decide whether to keep your notebook for future reference, or delete it entirely.
Resources you used:
- Google Colab notebook (stored in your Google Drive).
Keep everything running
No action needed. Choose this if you want to revisit your analysis, extend it with new questions, or use it as a reference for future projects.
- Your notebook stays in Google Drive under the Colab Notebooks folder.
- You can reopen it anytime at colab.research.google.com by clicking File, then Open notebook.
Pause - I'll come back to this later
Since Google Colab notebooks have no running processes once you close the tab, there is nothing to pause. Your notebook is already saved in Google Drive and uses no resources when the tab is closed.
- Close the Colab browser tab. Your notebook is automatically saved.
- When you return, reopen the notebook from Google Drive or Colab's recent files list.
Delete - I don't want to use this again
Remove your notebook from Google Drive to clean up completely.
- Open Google Drive at drive.google.com.
- Navigate to the Colab Notebooks folder.
- Right-click your notebook file and select Move to trash.
- Empty your trash to permanently delete the file.
That's a Wrap!
That's a Wrap!
Nice work! You just completed your first end-to-end data analysis using Python.
You went from a messy CSV file with missing values to cleaned data, real insights, and professional visualizations. That is the core data science workflow in action.
You learned how to:
- Loaded, cleaned, and explored a real-world pandas DataFrame with 8,000+ Netflix titles, handling missing values and engineering new columns.
- Used groupby, value_counts(), and filtering to answer real business questions about content trends, top-producing countries, and genre distribution.
- Created professional bar chart visualizations with matplotlib that communicate your findings clearly.
- Built a content recommender function that filters Netflix titles by genre, country, and year range.
Ready to quiz yourself?