CertSafari
    Snowflake SnowPro Advanced: MLOps Engineer (MLA-B01)· Lessons

    Domain 1 · Lesson 1/17

    Distributed Feature Engineering with Snowpark and Snowflake ML Preprocessors

    Construct distributed feature engineering pipelines.

    13 min read
    4% of exam
    7 sources
    Published 5 Oct 2026
    Docs as of 4 Oct 2026

    What you will be able to do

    • Explain why a Snowpark DataFrame is a lazy query and how to build one from a table, a stage or a SQL statement
    • Choose between open-source preprocessors, Snowflake ML preprocessors and Ray map_batches based on data scale and where compute runs
    • Build a Snowflake ML preprocessing Pipeline that fits and transforms a large table inside Snowflake
    • Decide when to write a transformation as a SQL string, as Snowpark constructs or as a UDF, and when Snowpark code needs a Snowpark-optimized warehouse
    • Analyze a feature engineering use case to decide whether to author it as SQL or as Snowpark, knowing that both execute in Snowflake

    Key concept

    Pushdown — Snowpark and Snowflake ML preprocessors don't bring rows to your client. They turn your Python into work that runs inside Snowflake, next to the data, on Snowflake-managed compute. Distributed feature engineering in Snowflake depends on that.

    1.Snowpark DataFrames are lazy queries

    In Snowpark, the DataFrame is the main way to query and process data, so every feature pipeline here starts with one. Its key property is laziness. A Snowpark DataFrame does not hold rows. It describes a relational dataset, much like a query that has not been run yet. Snowpark libraries exist for Java, Python and Scala, and the examples below use Python.

    Working with a DataFrame takes three steps. First you construct it from a data source using the Session. session.table() reads a table, view or stream. session.create_dataframe() takes local values. session.range() generates a sequence. session.read followed by a format method such as json or csv reads files in a stage. session.sql() wraps the result of a SQL statement. Second, you specify transformations: which columns to select, how to filter rows, and how to sort and group. Third, you call an action such as collect(). Only the action sends the generated SQL to Snowflake for execution.

    Building the DataFrame runs nothing; collect() sends the query to the serverpython
    >>> # Create a DataFrame with the "id" and "name" columns from the "sample_product_data" table.
    >>> # This does not execute the query.
    >>> df = session.table("sample_product_data").select(col("id"), col("name"))
    
    >>> # Send the query to the server for execution and
    >>> # return a list of Rows containing the results.
    >>> results = df.collect()

    Lazy evaluation matters for feature engineering. Because nothing runs until the end, Snowpark can defer transformations and batch many of them into a single operation. That cuts the data moved between your client and Snowflake and improves performance. And because the work is pushed down, you need no separate cluster: Snowflake runs the computation and manages scale.

    This laziness is also the starting point for analyzing a use case as SQL versus Snowpark. A DataFrame is a query that sends SQL to Snowflake when an action runs, so a SQL statement and a Snowpark DataFrame are not rival engines. Both execute in Snowflake, next to the data. Your analysis is about authoring, not about where the compute runs. The section "Choosing between SQL and Snowpark" below works through the authoring options.

    Checkpoint 1 of 7· Put it in order

    Put the steps for getting data into a Snowpark DataFrame in order

    1. 1.Construct the DataFrame from a source such as a table, a staged file or a SQL statement
    2. 2.Invoke an action such as collect() so the statement runs
    3. 3.Specify the transformations: selected columns, row filters, sorting and grouping

    Sources12

    2.Three ways to engineer features in Snowflake ML

    After the data is in a DataFrame, you choose how to transform it into features. Snowflake ML documents three approaches. It tells you to pick based on data size, performance requirements and how much custom transformation logic you need. The main difference between them is where the compute runs.

    How the three feature engineering approaches compare
    AspectOSS (including scikit-learn)Snowflake ML preprocessorsRay map_batches
    ScaleSmall & medium datasetsLarge/distributed dataLarge/distributed data
    Execution environmentIn memoryPushdown to the default warehouse that you’re using to run SQL queriesAcross nodes in a compute pool
    Compute resourcesSnowpark Container Services (Compute Pool)WarehouseSnowpark Container Services (Compute Pool)
    PerformanceFast for local, in-memory workloads; scale limited and non-distributedDesigned for scalable, distributed feature engineeringHighly parallel and resource-managed, excels on large/unstructured data
    Use case suitabilityQuickly prototyping and experimentationProduction workflows with large datasetsLarge data workflows that require custom resource controls

    Open-source preprocessors such as scikit-learn run in memory on a single node within Container Runtime. They are quick for prototyping, but they don't distribute. Read the table's two OSS cells together: "in memory" describes how the data is processed, and "Snowpark Container Services (Compute Pool)" names the compute that hosts the Container Runtime node doing that work. Neither is a warehouse. Only the Snowflake ML preprocessors list a warehouse as their compute. They are the warehouse-native option: their processing is distributed across warehouse compute resources. Ray map_batches runs custom functions in parallel across the nodes of a compute pool. Its execution is also lazy: nothing is processed until you materialize the dataset, which reduces memory use. Ray is the choice for large-scale processing with custom logic, especially on unstructured data.

    Checkpoint 2 of 7· Match them up

    Match each approach to where its processing runs

    Tap a term, then the definition that fits it.

    Sources3

    3.Snowflake ML preprocessors and Pipelines

    The Snowflake ML preprocessors are in snowflake.ml.modeling.preprocessing, and the Pipeline class that chains them is in snowflake.ml.modeling.pipeline. They look like scikit-learn, with two important differences. First, each preprocessor names its columns with input_cols and output_cols rather than receiving a column selection through a ColumnTransformer. Second, the input is a Snowpark DataFrame, usually from session.table(), not a pandas DataFrame held in memory. When you call fit_transform on the pipeline, the fit and the transform run in Snowflake as distributed work on the warehouse.

    A StandardScaler and a OneHotEncoder chained in a Snowflake ML Pipeline and fitted on a tablepython
    # Load your data from a Snowflake table as a DataFrame
    df = session.table('CUSTOMER_DATA')
    
    # Define Snowflake ML preprocessors
    scaler = StandardScaler(input_cols=['AGE', 'INCOME'], output_cols=['AGE_SCALED', 'INCOME_SCALED'])
    encoder = OneHotEncoder(input_cols=['CITY'], output_cols=['CITY_ENCODED'])
    
    pipeline = Pipeline(steps=[
        ('scaling', scaler),
        ('encoding', encoder)
    ])
    
    # Fit and transform data in Snowflake (distributed)
    result = pipeline.fit_transform(df)
    result.show()

    The fit step is what makes a scaler stateful. A min-max scaler, for example, learns the minimum and maximum values of each column from the training sample, and that learned state is what the transform step applies. The Snowflake guide describes such transformations as capturing the global state of the training sample, which is why they belong with the model rather than being recomputed on whatever data arrives later.

    Checkpoint 3 of 7· Fill the gap

    Which module completes this import of the Snowflake ML preprocessors?

    from snowflake.snowpark import Session
    from snowflake.ml.modeling. ?  import StandardScaler, OneHotEncoder
    from snowflake.ml.modeling.pipeline import Pipeline

    Answer to the reflection: refitting on the inference batch would learn new statistics, such as a different minimum and maximum, from that batch alone. Its features would then be scaled on a different basis from the one the model was trained on. Reuse the state captured from the training sample instead.

    Checkpoint 4 of 7· Exam question

    A team stores 2 billion customer rows in a Snowflake table. A data scientist calls `fit` on a `snowflake.ml.modeling.preprocessing.MinMaxScaler` using a Snowpark DataFrame built from that table. Where are the per-column minimum and maximum values computed?

    Sources3456

    4.Choosing between SQL and Snowpark

    "SQL or Snowpark" is less of a choice than it sounds. A Snowpark DataFrame evaluates by sending SQL statements to Snowflake, so both run on the same engine. The real decision is how you author the logic and where any custom code runs.

    Set-based logic you already have as SQL. session.sql() accepts a SQL string, and it can run SELECT statements over tables and staged files. The native Snowpark constructs, such as select and col, are still the better authoring option. They give intelligent code completion and type checking. For reading data, the docs also say session.table() and session.read give better syntax and error highlighting than embedding the same query in a string.

    Logic that SQL expresses poorly. For loops or batch functions, write a user-defined function. Snowpark sends the UDF code to the server, and Snowflake runs it in parallel next to the data, so you don't pull rows to the client.

    Python code that needs a lot of memory. Snowpark code runs on standard warehouses too. Snowpark-optimized warehouses are recommended for Snowpark workloads with large memory requirements or a dependency on a specific CPU architecture, such as ML training in a stored procedure on a single warehouse node. By default they provide 16x the memory per node of a standard warehouse. The resource_constraint property of CREATE or ALTER WAREHOUSE configures memory and CPU architecture. Creating or resuming one can take longer than a standard warehouse.

    These sources give no formal SQL-versus-Snowpark decision matrix. The guidance above is what they do support.

    Checkpoint 5 of 7· Check yourself

    A team needs a per-row transformation written as custom Python logic, and they must not pull the data to the client. Which approach fits?

    Snowpark-optimized warehouse memory options
    Memory (up to)RESOURCE_CONSTRAINT valuesMinimum warehouse size
    16GBMEMORY_1X, MEMORY_1X_x86XSMALL
    256GBMEMORY_16X, MEMORY_16X_x86M
    1TBMEMORY_64X, MEMORY_64X_x86L

    Checkpoint 6 of 7· Check yourself

    Which workload is Snowflake's recommendation for a Snowpark-optimized warehouse aimed at?

    Checkpoint 7 of 7· Exam question

    A fraud model was trained with a `snowflake.ml.modeling.preprocessing.OneHotEncoder` fitted on the `merchant_category` column. During batch inference the encoder raises an error because new merchant categories appeared that were absent from the training data. Which change allows scoring to continue without refitting?

    Sources217

    Exam traps

    Each one states something that sounds right. Open it to see what is actually true.

    1. 1.Snowflake ML preprocessors work like scikit-learn: they pull the table into client memory and transform it there.Why is that wrong?

      They are pushed down. The fit and transform run as distributed work on the warehouse, which is why they suit large datasets and production workloads.

      Covered in Snowflake ML preprocessors and Pipelines

    2. 2.A Snowpark-optimized warehouse is a general upgrade that speeds up any query.Why is that wrong?

      It targets Snowpark code with large memory or specific CPU-architecture needs. The extra memory per node solves memory pressure in that code, not general SQL performance.

      Covered in Choosing between SQL and Snowpark

    3. 3.Choosing SQL over Snowpark (or the reverse) decides whether the work runs inside Snowflake.Why is that wrong?

      Both do. A Snowpark DataFrame sends SQL statements to Snowflake when an action runs, so the choice is about how you author the logic, not where it executes.

      Covered in Snowpark DataFrames are lazy queries

    Sources

    Every claim above is drawn from one of these pages, quoted as it was written on the date shown.

    1. 1.
      “In a sense, a DataFrame is like a query that needs to be evaluated in order to retrieve data.”
      ↩︎ Snowpark DataFrames are lazy queries
      “using the table method and read property offer better syntax highlighting, error highlighting, and intelligent code completion in development tools”
      ↩︎ Choosing between SQL and Snowpark
      “A DataFrame represents a relational dataset that is evaluated lazily: it only executes when a specific action is triggered.”
      ↩︎ Prediction
      “you must invoke a method that performs an action (for example, the collect() method)”
      ↩︎ Checkpoint
    2. 2.
      “delay running data transformation until as late in the pipeline as possible while batching up many operations into a single operation”
      ↩︎ Snowpark DataFrames are lazy queries
      “No requirement for a separate cluster outside of Snowflake for computations.”
      ↩︎ Snowpark DataFrames are lazy queries
      “you benefit from features like intelligent code completion and type checking when you use the native language constructs provided by Snowpark”
      ↩︎ Choosing between SQL and Snowpark
      “creating as a UDF will allow Snowflake to parallelize and apply the codeful logic at scale within Snowflake”
      ↩︎ Choosing between SQL and Snowpark
      “Snowpark pushes down all data transformation and heavy lifting to the Snowflake data cloud”
      ↩︎ Key concept
      “sends the corresponding SQL statements to the Snowflake database for execution”
      ↩︎ Exam trap 3
    3. 3.
      “Choose the approach that best matches your data size, performance requirements, and need for custom transformation logic.”
      ↩︎ Three ways to engineer features in Snowflake ML
      “This approach is ideal for large-scale data processing with custom logic”
      ↩︎ Three ways to engineer features in Snowflake ML
      “use familiar Python ML libraries that run locally or on single nodes within Container Runtime”
      ↩︎ Three ways to engineer features in Snowflake ML
      “The Snowflake ML preprocessors are a subset of the preprocessors available in scikit-learn, but they cover the most common use cases.”
      ↩︎ Snowflake ML preprocessors and Pipelines
      “These preprocessors are pushed down to scale across warehouses.”
      ↩︎ Exam trap 1
      “These APIs distribute the processing across warehouse compute resources.”
      ↩︎ Checkpoint
    4. 4.
      “Leverage distributed preprocessing functions in snowflake.ml.modeling.preprocessing.”
      ↩︎ Snowflake ML preprocessors and Pipelines
    5. 5.
      “The Snowflake ML API reference includes documentation on all publicly-released functionality.”
      ↩︎ Snowflake ML preprocessors and Pipelines
    6. 6.
      “they capture the global state (e.g. minimum and maximum values for columns) of our training sample”
      ↩︎ Snowflake ML preprocessors and Pipelines
    7. 7.
      “Example workloads include Machine Learning (ML) training use cases using a stored procedure on a single virtual warehouse node.”
      ↩︎ Choosing between SQL and Snowpark
      “The default configuration for a Snowpark-optimized warehouse provides 16x memory per node compared to a standard warehouse.”
      ↩︎ Exam trap 2
      “recommended for running Snowpark workloads such as code that has large memory requirements or dependencies on a specific CPU architecture”
      ↩︎ Checkpoint

    Continue to page 2 of 2

    Storing and Loading ML Training and Inference Data: Tables, Stages and Data Shares

    Spotted a mistake, or was something unclear? Tell us.