Analyzing Sales Data Using Window Functions in Apache Spark
📖 Scenario: You work for a retail company that wants to analyze monthly sales data for different stores. You have a dataset with sales amounts for each store by month. Your task is to calculate the running total of sales for each store over the months using window functions.
🎯 Goal: Build a Spark program that uses window functions to calculate the cumulative sales for each store by month.
📋 What You'll Learn
Create a Spark DataFrame with sales data for stores and months
Define a window specification partitioned by store and ordered by month
Use the window function to calculate cumulative sales
Display the final DataFrame with cumulative sales
💡 Why This Matters
🌍 Real World
Retail companies often analyze sales trends over time per store to make inventory and marketing decisions. Window functions help calculate running totals and rankings easily.
💼 Career
Data analysts and data scientists use window functions in Spark to perform advanced data analysis on large datasets efficiently.
Progress0 / 4 steps
1
Create the sales DataFrame
Create a Spark DataFrame called sales_df with these exact rows: ("StoreA", 1, 100), ("StoreA", 2, 150), ("StoreB", 1, 200), ("StoreB", 2, 300). The columns should be store, month, and sales.
Apache Spark
Hint
Use spark.createDataFrame() with a list of tuples and specify the column names.
2
Define the window specification
Create a window specification called window_spec that partitions data by store and orders by month in ascending order. Use Window.partitionBy("store").orderBy("month").
Apache Spark
Hint
Import Window from pyspark.sql and use partitionBy and orderBy.
3
Calculate cumulative sales using window function
Add a new column called cumulative_sales to sales_df that contains the running total of sales for each store ordered by month. Use F.sum("sales").over(window_spec) and assign the result back to sales_df.
Apache Spark
Hint
Use withColumn and F.sum().over(window_spec) to create the cumulative sales column.
4
Display the final DataFrame
Use sales_df.show() to display the DataFrame with the new cumulative_sales column.
Apache Spark
Hint
Call show() on sales_df to print the table.
Practice
(1/5)
1. What is the main purpose of window functions in Apache Spark?
easy
A. To perform calculations across rows related to the current row without collapsing the data
B. To group data and reduce the number of rows
C. To filter rows based on a condition
D. To join two datasets together
Solution
Step 1: Understand window function behavior
Window functions calculate values across related rows but keep all original rows intact.
Step 2: Compare with grouping
Grouping reduces rows by aggregation, but window functions add columns without reducing rows.
Final Answer:
To perform calculations across rows related to the current row without collapsing the data -> Option A
Quick Check:
Window functions add calculations without grouping ≠ A [OK]
Hint: rank() gives same rank to ties, skips next ranks [OK]
Common Mistakes:
Confusing rank() with dense_rank()
Assigning different ranks to tied values
Not ordering data before applying rank
4. Identify the error in this PySpark code snippet using window functions:
from pyspark.sql.window import Window
from pyspark.sql.functions import row_number
windowSpec = Window.partitionBy('department')
df = df.withColumn('row_num', row_number().over(windowSpec.orderBy('salary')))
medium
A. Missing import for Window functions causes error
B. windowSpec.orderBy('salary') is valid; no error in code
C. row_number() cannot be used with partitionBy
D. windowSpec.orderBy('salary') is invalid; orderBy should be called on Window, not on windowSpec
Solution
Step 1: Check windowSpec usage
windowSpec is a WindowSpec object; calling orderBy on it is valid and returns a new WindowSpec.
Step 2: Confirm chaining
Chaining orderBy on windowSpec is allowed to refine the window specification.
Final Answer:
windowSpec.orderBy('salary') is valid; no error in code -> Option B
Quick Check:
WindowSpec supports chaining orderBy to refine window [OK]
Hint: WindowSpec supports chaining orderBy to refine window [OK]
Common Mistakes:
Calling orderBy on windowSpec instead of Window
Assuming row_number can't be used with partitionBy
Forgetting to import Window or functions
5. You have a sales dataset with columns: 'store', 'date', and 'sales'. You want to add a column showing the 3-day moving average of sales per store ordered by date. Which PySpark window function setup and code will achieve this?
hard
A. Use Window.partitionBy('store').orderBy('date').rowsBetween(0, 2) and avg('sales').over(windowSpec)
B. Use Window.partitionBy('store').orderBy('date').rangeBetween(-2, 0) and avg('sales').over(windowSpec)
C. Use Window.orderBy('date').rowsBetween(-3, 0) and avg('sales').over(windowSpec)
D. Use Window.partitionBy('store').orderBy('date').rowsBetween(-2, 0) and avg('sales').over(windowSpec)
Solution
Step 1: Define window for 3-day moving average per store
Partition by 'store' to separate stores, order by 'date' for time sequence, use rowsBetween(-2, 0) for current and previous 2 rows.
Step 2: Apply avg() over this window
Use avg('sales').over(windowSpec) to compute moving average over the defined window.
Final Answer:
Use Window.partitionBy('store').orderBy('date').rowsBetween(-2, 0) and avg('sales').over(windowSpec) -> Option D
Quick Check:
rowsBetween(-2,0) for 3-day window, partition by store [OK]
Hint: Use rowsBetween(-2,0) for 3-row moving average [OK]
Common Mistakes:
Using rangeBetween instead of rowsBetween for row count
Not partitioning by store
Using wrong rowsBetween range (like 0 to 2)
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.