Bird
Raised Fist0
Apache Sparkdata~10 mins

Windowed aggregations in Apache Spark - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Windowed aggregations
Start with DataFrame
↓
Define Window Spec
↓
Apply Aggregation over Window
↓
Add Result as New Column
↓
View Resulting DataFrame
Windowed aggregations apply calculations over a sliding group of rows defined by a window, adding results as new columns.
Execution Sample
Apache Spark
from pyspark.sql import SparkSession
from pyspark.sql.window import Window
from pyspark.sql.functions import sum

spark = SparkSession.builder.getOrCreate()
data = [(1, 'A', 10), (2, 'A', 20), (3, 'A', 30), (4, 'B', 40), (5, 'B', 50)]
df = spark.createDataFrame(data, ['id', 'group', 'value'])

windowSpec = Window.partitionBy('group').orderBy('id').rowsBetween(-1, 0)
df = df.withColumn('rolling_sum', sum('value').over(windowSpec))
df.show()
This code calculates a rolling sum of 'value' over the current and previous row within each 'group'.
Execution Table
StepRow (id, group, value)Window Rows IncludedAggregation (sum)New Column 'rolling_sum'
1(1, A, 10)Rows with id 11010
2(2, A, 20)Rows with id 1, 210 + 20 = 3030
3(3, A, 30)Rows with id 2, 320 + 30 = 5050
4(4, B, 40)Rows with id 44040
5(5, B, 50)Rows with id 4, 540 + 50 = 9090
6End of DataFrame---
💡 All rows processed; rolling sums computed for each row within their group windows.
Variable Tracker
VariableStartAfter Step 1After Step 2After Step 3After Step 4After Step 5Final
rolling_sumN/A103050409090
Key Moments - 2 Insights
Why does the rolling sum for id=3 only include values from id=2 and id=3, not id=1?
Because the window is defined with rowsBetween(-1, 0), it includes the current row and one previous row only, so for id=3 it includes id=2 and id=3 rows (see execution_table row 3).
Why are rows partitioned by 'group' before applying the window aggregation?
Partitioning by 'group' means the window aggregation only sums values within the same group, so rows from group 'A' and 'B' are handled separately (see execution_table rows 1-3 vs 4-5).
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table at Step 2. What is the rolling_sum value for row with id=2?
A30
B10
C20
D50
💡 Hint
Check the 'New Column rolling_sum' value in execution_table row 2.
At which step does the rolling_sum first include two rows in its window?
AStep 1
BStep 4
CStep 2
DStep 5
💡 Hint
Look at the 'Window Rows Included' column in execution_table to see when two rows are included.
If the window was changed to rowsBetween(-2, 0), what would be the rolling_sum for id=3?
A50
B60
C30
D10
💡 Hint
With rowsBetween(-2, 0), the window includes current and two previous rows; sum values for id=1,2,3.
Concept Snapshot
Windowed aggregations in Spark:
- Define a window with partitionBy and orderBy
- Use rowsBetween to set frame (e.g., current and previous rows)
- Apply aggregation function over window (sum, avg, etc.)
- Result added as new column
- Useful for rolling calculations within groups
Full Transcript
Windowed aggregations in Apache Spark let you calculate values like sums or averages over a sliding window of rows. You start with a DataFrame, define a window specification that partitions data into groups and orders rows. Then you apply an aggregation function over this window, which can include the current row and some number of previous or following rows. The result is added as a new column to the DataFrame. For example, a rolling sum over the current and previous row within each group shows how values accumulate step-by-step. This method helps analyze trends and patterns within grouped data.

Practice

(1/5)
1. What is the main purpose of using windowed aggregations in Apache Spark?
easy
A. To perform calculations over a group of rows without collapsing them into a single result
B. To join two DataFrames based on a key column
C. To filter rows based on a condition
D. To sort the entire DataFrame globally

Solution

  1. Step 1: Understand windowed aggregation concept

    Windowed aggregations allow calculations like sums or averages over a set of rows related to the current row, without reducing the number of rows.
  2. Step 2: Compare with other operations

    Joins combine tables, filters remove rows, and sorting orders rows globally, but do not perform grouped calculations without collapsing rows.
  3. Final Answer:

    To perform calculations over a group of rows without collapsing them into a single result -> Option A
  4. Quick Check:

    Windowed aggregation = grouped calculation without row collapse [OK]
Hint: Windowed means grouped but keeps all rows [OK]
Common Mistakes:
  • Confusing windowed aggregation with join operations
  • Thinking windowed aggregation filters rows
  • Assuming windowed aggregation sorts globally
2. Which of the following is the correct way to define a window specification that partitions data by 'department' and orders by 'salary' in ascending order?
easy
A. Window.orderBy('department').partitionBy('salary')
B. Window.partitionBy('department').orderBy('salary')
C. Window.partitionBy('salary').orderBy('department')
D. Window.orderBy('salary').partitionBy('department')

Solution

  1. Step 1: Recall window specification syntax

    In Spark, window specs use partitionBy first to group, then orderBy to sort within groups.
  2. Step 2: Check option order and columns

    Window.partitionBy('department').orderBy('salary') correctly partitions by 'department' and orders by 'salary'. Other options reverse or swap columns incorrectly.
  3. Final Answer:

    Window.partitionBy('department').orderBy('salary') -> Option B
  4. Quick Check:

    partitionBy then orderBy = correct window spec [OK]
Hint: partitionBy groups first, orderBy sorts inside groups [OK]
Common Mistakes:
  • Swapping partitionBy and orderBy order
  • Using wrong columns in partitionBy or orderBy
  • Confusing partitionBy with filter
3. Given the following Spark code, what will be the output for the 'running_total' column?
from pyspark.sql import SparkSession
from pyspark.sql.window import Window
from pyspark.sql.functions import sum

spark = SparkSession.builder.getOrCreate()
data = [(1, 'A', 10), (2, 'A', 20), (3, 'A', 30), (4, 'B', 40)]
df = spark.createDataFrame(data, ['id', 'group', 'value'])

windowSpec = Window.partitionBy('group').orderBy('id').rowsBetween(Window.unboundedPreceding, Window.currentRow)
df = df.withColumn('running_total', sum('value').over(windowSpec))
df.orderBy('id').show()
medium
A. [10, 30, 60, 100]
B. [10, 20, 30, 40]
C. [10, 30, 60, 40]
D. [10, 20, 50, 40]

Solution

  1. Step 1: Understand window specification

    The window partitions by 'group' and orders by 'id'. The frame includes all rows from the start to the current row in that group.
  2. Step 2: Calculate running totals per group

    For group 'A': id=1 value=10 running_total=10; id=2 value=20 running_total=10+20=30; id=3 value=30 running_total=10+20+30=60. For group 'B': id=4 value=40 running_total=40.
  3. Final Answer:

    [10, 30, 60, 40] -> Option C
  4. Quick Check:

    Running total sums values up to current row per group [OK]
Hint: Running total sums values up to current row in partition [OK]
Common Mistakes:
  • Not partitioning by group, summing all rows
  • Misunderstanding rowsBetween frame
  • Mixing order of rows in calculation
4. Identify the error in the following Spark code snippet that tries to calculate a moving average over the last 2 rows including the current row:
from pyspark.sql.window import Window
from pyspark.sql.functions import avg

windowSpec = Window.partitionBy('category').orderBy('date').rowsBetween(-2, 0)
df = df.withColumn('moving_avg', avg('sales').over(windowSpec))
medium
A. partitionBy should be orderBy for moving average
B. orderBy column 'date' must be included in select
C. avg function cannot be used with window functions
D. rowsBetween frame is incorrect; it should be rowsBetween(-1, 0) for last 2 rows

Solution

  1. Step 1: Understand rowsBetween frame

    rowsBetween(-2, 0) includes current row and two preceding rows, totaling 3 rows, not 2.
  2. Step 2: Correct frame for last 2 rows

    To include current and previous row (2 rows total), use rowsBetween(-1, 0).
  3. Final Answer:

    rowsBetween frame is incorrect; it should be rowsBetween(-1, 0) for last 2 rows -> Option D
  4. Quick Check:

    rowsBetween(-1,0) = last 2 rows including current [OK]
Hint: rowsBetween counts rows including current, so -1 means one before [OK]
Common Mistakes:
  • Using wrong rowsBetween range for desired window size
  • Confusing partitionBy and orderBy roles
  • Thinking avg can't be used with window
5. You have a sales DataFrame with columns: 'store', 'date', and 'sales'. You want to calculate a 7-day moving average of sales per store, but some dates are missing for certain stores. Which approach correctly handles missing dates to compute the moving average using windowed aggregations?
hard
A. Fill missing dates with zero sales before applying a window partitioned by 'store' and ordered by 'date' with rowsBetween(-6, 0)
B. Use partitionBy('store') and orderBy('date') with rowsBetween(-7, 0) directly on original data without filling missing dates
C. Apply a global window without partitioning and order by 'date' only
D. Calculate moving average using groupBy('store', 'date') and avg('sales') without window functions

Solution

  1. Step 1: Understand missing dates impact

    Missing dates cause gaps in ordering, so rowsBetween(-6, 0) won't cover full 7 days if dates are missing.
  2. Step 2: Fill missing dates with zero sales

    Filling missing dates ensures continuous date sequence per store, so window frame covers exact 7 days.
  3. Step 3: Apply window with partition and order

    Partition by 'store', order by 'date', and use rowsBetween(-6, 0) to get 7-day moving average correctly.
  4. Final Answer:

    Fill missing dates with zero sales before applying a window partitioned by 'store' and ordered by 'date' with rowsBetween(-6, 0) -> Option A
  5. Quick Check:

    Fill gaps first, then window for accurate moving average [OK]
Hint: Fill missing dates to avoid gaps in window frame [OK]
Common Mistakes:
  • Ignoring missing dates causing wrong window frames
  • Using global window ignoring store partitions
  • Using groupBy instead of window for moving average
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard