Skip to content
Project: Analyzing Online Sports Revenue
Sports clothing and athleisure attire is a huge industry, worth approximately $193 billion in 2021 with a strong growth forecast over the next decade! (Source: https://www.statista.com/statistics/254489/total-revenue-of-the-global-sports-apparel-market/)
In this workbook, you will undertake the role of a product analyst for an online sports clothing company. The company is specifically interested in how it can improve revenue. You will dive into product data such as pricing, reviews, descriptions, and ratings, as well as revenue and website traffic, to produce recommendations for its marketing and sales teams.
The data:
You've been provided with four datasets to investigate:
brands.csv
| Columns | Description |
|---|---|
product_id | Unique product identifier |
brand | Brand of the product |
finance.csv
| Columns | Description |
|---|---|
product_id | Unique product identifier |
listing_price | Original price of the product |
sale_price | Discounted price of the product |
discount | Discount off the listing price, as a decimal |
revenue | Revenue generated by the product |
info.csv
| Columns | Description |
|---|---|
product_name | Name of the product |
product_id | Unique product identifier |
description | Description of the product |
reviews.csv
| Columns | Description |
|---|---|
product_id | Unique product identifier |
rating | Average product rating |
reviews | Number of reviews for the product |
# Importing libraries
import pandas as pd
# Loading the data
brands = pd.read_csv("brands.csv")
finance = pd.read_csv("finance.csv")
info = pd.read_csv("info.csv")
reviews = pd.read_csv("reviews.csv")
# Start coding here...Task 1: Adidas vs Nike Analysis by Price Quartiles
# Step 1 & 2: Merge and drop nulls
merged_df = info.merge(finance, on='product_id') \
.merge(brands, on='product_id') \
.merge(reviews, on='product_id')
merged_df.dropna(inplace=True)
# Step 3: Create price labels
quartiles = merged_df['listing_price'].quantile([0.25, 0.5, 0.75])
def label_price(price):
if price <= quartiles[0.25]:
return "Budget"
elif price <= quartiles[0.5]:
return "Average"
elif price <= quartiles[0.75]:
return "Expensive"
else:
return "Elite"
merged_df['price_label'] = merged_df['listing_price'].apply(label_price)
# Step 4: Filter for Adidas and Nike
filtered = merged_df[merged_df['brand'].isin(['Adidas', 'Nike'])]
# Step 5: Group and aggregate
adidas_vs_nike = filtered.groupby(['brand', 'price_label']).agg(
num_products=('product_id', 'count'),
mean_revenue=('revenue', 'mean')
).reset_index()
# Step 6: Round numeric values
adidas_vs_nike['mean_revenue'] = adidas_vs_nike['mean_revenue'].round(2)
adidas_vs_nike['num_products'] = adidas_vs_nike['num_products'].round(2)
Task 2: Description Length vs Rating and Reviews
# Step 1: Create description length column
merged_df['description_length'] = merged_df['description'].str.len()
# Step 2: Define bins and labels
bins = [0, 100, 200, 300, 400, 500, 600, 700]
labels = ['100', '200', '300', '400', '500', '600', '700']
# Step 3: Bin using pd.cut
merged_df['description_length'] = pd.cut(
merged_df['description_length'],
bins=bins,
labels=labels,
include_lowest=True,
right=True # e.g., 100 goes into '100'
)
# Step 4: Group and calculate stats
description_lengths = merged_df.groupby('description_length').agg(
mean_rating=('rating', 'mean'),
total_reviews=('reviews', 'sum')
).reset_index()
# Step 5: Round values
description_lengths['mean_rating'] = description_lengths['mean_rating'].round(2)
description_lengths['total_reviews'] = description_lengths['total_reviews'].round(2)