Python Data Analysis Examples
Table of Contents + −
In the last lesson, Data Cleaning Basics, you learned to fix messy data. So now you have all the pieces: load a file, clean it, select and filter it. The question is, how do they fit together on a real job? That is what this lesson is. We take a small dataset of orders and answer real business questions about it, start to finish. By the end you will see the full rhythm of a data analysis, and meet the one tool that ties it all together: groupby.
🤔 What does “analyzing data” actually mean?
Analysis sounds fancy, but it just means asking questions of your data and getting answers backed by numbers. Not guessing. Counting.
A real analysis usually answers questions like:
- How much did we sell in total?
- Which product sells the most?
- What is the average order value per city?
- Who are our top customers?
Every one of these is just a count, a sum, or an average over a group of rows. Pandas does all of them in a line or two. Let’s see it on a real table.
🧱 Our dataset
Here is a small table of orders. In real life this would come from a CSV with pd.read_csv, but we will build it directly so you can run the whole lesson without a file.
import pandas as pd
data = { "order_id": [1, 2, 3, 4, 5, 6, 7, 8], "customer": ["Alex", "Riya", "Alex", "Maria", "Riya", "Sam", "Alex", "Maria"], "product": ["Pen", "Notebook", "Pen", "Bag", "Pen", "Notebook", "Bag", "Pen"], "city": ["London", "Mumbai", "London", "Toronto", "Mumbai", "London", "London", "Toronto"], "amount": [50, 120, 50, 800, 50, 120, 800, 50]}
df = pd.DataFrame(data)print(df.head())Output
order_id customer product city amount0 1 Alex Pen London 501 2 Riya Notebook Mumbai 1202 3 Alex Pen London 503 4 Maria Bag Toronto 8004 5 Riya Pen Mumbai 50So each row is one order: who bought it, what product, in which city, and the amount. Now let’s ask questions.
💰 Simple totals and counts
The easiest questions are about the whole table. You sum a column, or count its rows, in one call.
This answers “how much did we sell” and “how many orders”:
print("Total sales:", df["amount"].sum())print("Number of orders:", len(df))print("Average order:", df["amount"].mean())print("Biggest order:", df["amount"].max())Output
Total sales: 1990Number of orders: 8Average order: 248.75Biggest order: 800Each line is one question:
df["amount"].sum()adds up every order amount, giving total sales.len(df)counts the rows, which is the number of orders..mean()and.max()give the average and the largest order.
These whole-table numbers are a good first look. But the real value comes from breaking the data into groups.
📊 Grouping with groupby
Here is the most important tool in data analysis. groupby splits the table into groups that share a value, then runs a calculation on each group. It answers “per something” questions, like sales per city or orders per customer.
This finds the total sales for each city:
sales_by_city = df.groupby("city")["amount"].sum()print(sales_by_city)Output
cityLondon 1700Mumbai 170Toronto 1600Name: amount, dtype: int64Read the line left to right, because that is exactly how it works:
df.groupby("city")splits the rows into groups, one per city.["amount"]picks the amount column inside each group..sum()adds that column up for each group.
So you get one total per city, all at once. London sold 1700, Mumbai 170, Toronto 1600. You can swap .sum() for .mean() to get the average per group, or .count() to count rows per group. The pattern is always the same: group, pick a column, calculate.
This shows the average order amount per customer instead:
avg_by_customer = df.groupby("customer")["amount"].mean()print(avg_by_customer)Output
customerAlex 300.000000Maria 425.000000Riya 85.000000Sam 120.000000Same pattern, different question. We grouped by customer this time and asked for the average. That is the power of groupby: change the column or the calculation and you answer a brand new question with almost the same line.
🔢 Counting categories with value_counts
A very common question is “how many of each?” For that, value_counts counts how often each value appears in a column.
This counts how many orders each product had:
print(df["product"].value_counts())Output
productPen 4Bag 2Notebook 2Name: count, dtype: int64So Pen was ordered 4 times, Bag and Notebook twice each. value_counts also sorts by the highest count first, so the most common item is right at the top. It is the fastest way to see what is popular.
⬆️ Sorting the results
Once you have numbers, you usually want them in order, biggest first. sort_values reorders the rows by a column.
This sorts the city totals from highest to lowest:
sales_by_city = df.groupby("city")["amount"].sum()ranked = sales_by_city.sort_values(ascending=False)print(ranked)Output
cityLondon 1700Toronto 1600Mumbai 170Name: amount, dtype: int64The key is ascending=False, which means largest first. Without it, sorting goes smallest first. Now you can instantly see London is the top city and Mumbai the lowest. Sorting turns a pile of numbers into a clear ranking.
🖥️ Putting it all together
Here is a complete mini-analysis that answers several questions in one script. This is the real flow you would write on the job.
import pandas as pd
data = { "customer": ["Alex", "Riya", "Alex", "Maria", "Riya", "Sam", "Alex", "Maria"], "product": ["Pen", "Notebook", "Pen", "Bag", "Pen", "Notebook", "Bag", "Pen"], "city": ["London", "Mumbai", "London", "Toronto", "Mumbai", "London", "London", "Toronto"], "amount": [50, 120, 50, 800, 50, 120, 800, 50]}df = pd.DataFrame(data)
print("Total sales:", df["amount"].sum())print("\nTop product:")print(df["product"].value_counts().head(1))print("\nSales per city (high to low):")print(df.groupby("city")["amount"].sum().sort_values(ascending=False))print("\nTop customer by spend:")print(df.groupby("customer")["amount"].sum().sort_values(ascending=False).head(1))Output
Total sales: 1990
Top product:productPen 4Name: count, dtype: int64
Sales per city (high to low):cityLondon 1700Toronto 1600Mumbai 170Name: amount, dtype: int64
Top customer by spend:customerAlex 900Name: amount, dtype: int64Look at what you just did with a handful of lines. You found total sales, the most-ordered product, a city ranking, and the top customer. No spreadsheets, no manual counting. That is data analysis: ask a question, write a short Pandas line, read the answer.
🛠️ Practice Challenge
Try these on the same df. Each one is one or two lines of Pandas. Give it a real attempt before opening the answer.
Question 1: How many orders did each customer place? (Hint: count rows per customer.)
Question 2: What is the total amount sold for each product, ranked from highest to lowest?
⚠️ Common Mistakes
A few traps in analysis:
- Forgetting to pick a column after
groupby.df.groupby("city").sum()tries to sum every column, which can include ones that make no sense. Pick the column you mean:df.groupby("city")["amount"].sum(). - Reading an unsorted result as a ranking.
groupbyreturns groups in label order, not by size. Addsort_values(ascending=False)when you want a ranking. - Confusing
value_countsandgroupby. Usevalue_countsto count how often each value appears. Usegroupbywhen you want to sum or average another column per group.
✅ Best Practices
Habits for clean analysis:
- Always clean the data first (blanks, duplicates, types) before you trust any total or average.
- Build the analysis one question at a time. Print each result before moving to the next.
- Name your results clearly, like
sales_by_city, so the code reads like the questions you are asking. - Remember the group, pick, calculate, sort pattern. Most “per something” questions follow it exactly.
🧩 What You’ve Learned
✅ Analysis means asking questions of your data and answering them with counts, sums, and averages.
✅ Whole-table numbers come from df["col"].sum(), .mean(), .max(), and len(df).
✅ groupby splits the table into groups and calculates per group, the heart of “per something” questions.
✅ value_counts counts how often each value appears, and sort_values(ascending=False) ranks results biggest first.
✅ A real analysis is just these small steps in a row: load, clean, group, calculate, sort, read the answer.
Check Your Knowledge
Test what you learned. Pick an answer for each question, then click Check.
- 1
What does df.groupby("city")["amount"].sum() do?
Why: groupby splits the rows into groups that share a city, then .sum() totals the amount column within each group, giving one total per city.
- 2
Which tool best answers 'how many orders had each product'?
Why: value_counts() counts how often each value appears in a column, so it directly answers how many orders each product had, sorted highest first.
- 3
Your grouped totals are not in ranking order. How do you fix that?
Why: groupby returns groups in label order, not by size. sort_values(ascending=False) reorders the result with the biggest number first.
- 4
What is the usual pattern for a 'per something' question in Pandas?
Why: Most per-group questions follow group (groupby), pick a column, calculate (sum/mean/count), then sort the result to rank it.
🚀 What’s Next?
You can now take raw data from a file all the way to real answers. That is the full data analysis skill. From here, the next big step is teaching the computer to find patterns on its own. That is machine learning, and it starts with understanding how Python powers the whole world of AI.