Study guide
14.2 Pandas-on-Spark Operations, Indexing, and Optimization
Databricks Certified Associate Developer for Apache Spark — Free Study Guide 2026 Exam
Track your progress as you read
Finished sections get a check mark.
1 Chapter 1: Spark Architecture and Execution
1.1 Spark Benefits, Modules, and DataFrame/Dataset Concepts 1.2 Driver, Executors, and Cluster Managers 1.3 Execution Hierarchy: Applications, Jobs, Stages, and Tasks 1.4 Lazy Evaluation, Transformations vs Actions, and Resilient Lineage
2 Chapter 2: Shuffles, Memory and Persistence
2.1 Narrow vs Wide Dependencies and the Shuffle Mechanism 2.2 Memory Management, Fault Tolerance, and Garbage Collection 2.3 Caching, Persistence, and StorageLevels
3 Chapter 3: Spark SQL Sessions, Tables and Views
3.1 SparkSession, Catalogs, Databases, and Namespaces 3.2 Managed vs External Tables and CTAS 3.3 Views: Temporary vs Global Temporary Views
4 Chapter 4: SQL Sources and Stored Layout
4.1 JDBC Reads, Writes, and Parallelism 4.2 Direct File SQL, Save Modes, and Persistent Layout
5 Chapter 5: SQL Queries and Analytics
5.1 SQL Queries, CTEs, Subqueries, and Built-in Expressions 5.2 Built-in SQL Expressions and an Integrated Query 5.3 Window Functions and Complex Joins in Spark SQL 5.4 SQL Join Semantics and Integrated Analytics
6 Chapter 6: DataFrame Construction and Columns
6.1 DataFrame Construction, Schemas, and StructTypes 6.2 Column Operations: Selecting, Renaming, Deriving, and Casting 6.3 Complex Nested Types and User-Defined Functions
7 Chapter 7: DataFrame Validation and Inspection
7.1 Row Operations: Filtering, Sorting, and Deduplication 7.2 Handling Missing and Null Data 7.3 Schema Inspection, Row Iteration, and List Conversion
8 Chapter 8: Aggregations and Dates
8.1 Grouping, Multi-Dimensional Aggregations, and Pivoting 8.2 Dates, Unix Epoch, and Time-Zone Conversions
9 Chapter 9: DataFrame Joins and File IO
9.1 DataFrame Joins and Combining Datasets 9.2 Data Sources, SaveModes, and Partitioning
10 Chapter 10: Shared Variables and Stateful Processing
10.1 Broadcast Variables, Accumulators, and Closures 10.2 Stateless UDFs, Stateful Operators, and StateStores
11 Chapter 11: Troubleshooting and Tuning
11.1 Diagnosing Performance with the Spark UI & Execution Plans 11.2 Data Skew and Partition Tuning: repartition vs coalesce 11.3 Join Optimization and Broadcast Hash Joins
12 Chapter 12: Structured Streaming
12.1 Streaming Architecture, Sources, and Sinks 12.2 Output Modes, Triggers, and Checkpointing 12.3 Event-Time Processing, Watermarking, and Windowing 12.4 Streaming Deduplication With and Without Watermarks
13 Chapter 13: Spark Connect and Deployment
13.1 Spark Connect Architecture & Client-Server Decoupling 13.2 Working with Spark Connect: Connections and Best Practices
14 Chapter 14: Pandas API on Spark
14.1 Pandas API on Apache Spark: Core Architecture and Syntax 14.2 Pandas-on-Spark Operations, Indexing, and Optimization
14.2 Pandas-on-Spark Operations, Indexing, and Optimization
Key Takeaways Explain This Topic AI
Use ps.set_option("compute.default_index_type", ...) to select a default index; Spark 3.5 uses distributed-sequence by default.
sequence can introduce a single-partition bottleneck; distributed indices have gaps and are not durable business keys.
Cross-frame arithmetic aligns index labels and may require joins/shuffles; verify index meaning before enabling compute.ops_on_diff_frames.
Use psdf.pandas_on_spark.transform_batch for same-length batch transformations; batch-local aggregates are not global aggregates.
Last updated: October 2026
Distributed indices and their costs
A pandas index identifies rows for label-based selection and arithmetic. A distributed Spark DataFrame has no implicit stable row order. Pandas API on Spark provides an index abstraction, but its construction and alignment can require distributed work. This distinction explains why familiar small-data code can become slow or change meaning at scale. Choose an existing business key when it represents the intended identity; do not treat generated IDs as durable keys across repartitioning or reloads. import pyspark.pandas as ps
ps.set_option("compute.default_index_type", "distributed-sequence")
The option name is compute.default_index_type, with an underscore between index and type. In Spark 3.5, distributed-sequence is the default. Check the installed version rather than copying another runtime's defaults. An index is not a database index that accelerates arbitrary lookups. It is a logical row-label column translated into Spark operations.
- Index choice Behavior Main consideration
- sequence Consecutive labels using a global ordering/window Can collapse work into one partition
distributed-sequence Consecutive labels generated with distributed coordination Default compromise; IDs can change with the plan
distributed Unique nonconsecutive generated IDs Avoids the global consecutive-number requirement
Existing index column Uses meaningful supplied row labels Validate uniqueness/nulls according to the application
For a distributed index backed by monotonically_increasing_id(), the current implementation places partition IDs in the upper 31 bits and within-partition record numbers in the lower 33 bits. Thus one partition can contain 0, 1, 2 and another can begin at 8,589,934,592. The values have gaps. They depend on partition IDs and are not a stable business ordering, ranking, or a count of earlier records. Repartitioning can change them. Do not infer a missing record from a gap.
Arithmetic aligns labels, not physical positions
Suppose revenue and cost come from different frames. Subtracting their Series is an index alignment operation, not a promise to zip whatever happens to be the first row of each partition. In Spark 3.5, compute.ops_on_diff_frames defaults to false to guard against expensive accidental joins. If the frames have different anchors, the library can reject the expression. Enabling the option allows supported cross-frame operations, which can add joins and shuffles; exact join behavior depends on the operation. with ps.option_context("compute.ops_on_diff_frames", True):
difference = revenue_series - cost_series
Before enabling it, verify that both indices identify the same entities. Two independently generated RangeIndex-like sequences do not prove that customer labels match. When combining data by customer_id, an explicit merge on customer_id is usually easier to reason about. Inspect the resulting Spark plan using psdf.spark.explain(), compare row counts, and check unexpected missing labels or many-to-many key multiplication. An explicit merge can still shuffle; its advantage is deliberate identity semantics.
Batch functions see batches, not the whole dataset
Pandas-on-Spark offers the pandas_on_spark accessor for batch transformation. The DataFrame method is psdf.pandas_on_spark.transform_batch(func), not psdf.transform_batch(func). Its function receives a native pandas batch and must return the same number of rows. Use a transformation with meaning that does not depend on arbitrary batch boundaries. import pandas as pd
import pyspark.pandas as ps
psdf = ps.DataFrame({"meters": [0.0, 1000.0, 2500.0]})
def to_kilometers(pdf):
- return pd.DataFrame({"kilometers": pdf["meters"] / 1000.0},
- index=pdf.index)
converted = psdf.pandas_on_spark.transform_batch(to_kilometers)
The expected values are 0.0, 1.0 and 2.5 regardless of how rows are batched. In contrast, computing (pdf - pdf.min()) / (pdf.max() - pdf.min()) inside this function scales each batch separately. It does not compute global min/max scaling, and a constant batch can divide by zero. Compute global statistics explicitly and apply fixed values when global normalization is required. A return annotation must use the supported pandas-on-Spark type-hint conventions; omitting one can require sampling to infer the result schema.
Arrow batch interchange can reduce row-oriented conversion overhead, but it does not make arbitrary Python code automatically vectorized or free of copying. Built-in distributed arithmetic is preferable for a simple division like the example; the batch function is shown to explain the API contract. Pandas UDFs in the Spark SQL API are a separate interface using pandas_udf and Column expressions. Neither interface requires collecting the full dataset into driver pandas.
Practical performance decisions
Use distributed groupby and explicitly keyed merges for large data, and inspect their shuffles. A global sort or an unpartitioned sequence index can become a bottleneck. A rolling window of 7 means seven observations, not automatically seven calendar days; missing days, index ordering and group boundaries matter. Use an event-time Spark window for a time-based requirement when that is the clearer contract.
Methods such as iterrows() transfer rows through a local iterator and usually forfeit distributed transformation benefits. to_pandas() collects the result locally and must fit memory. A supported inplace=True operation updates the pandas-facing object, but does not turn Spark's underlying immutable plan into mutable shared worker memory. Confirm supported arguments rather than assuming every pandas option is implemented.
For each workflow, identify the row key, whether order matters, whether the calculation is batch-local or global, and where materialization occurs. Then inspect the plan and collect only suitably bounded results. Distributed execution adds coordination costs, so native pandas can be the right tool for genuinely small in-memory data; choose from measured size and the required operations.
Official reference
Pandas API options — source checked October 16, 2026. The examples state their runtime assumptions.