What you will be able to do
- Explain how Snowpark DataFrames and pandas on Snowflake defer work and push it down to Snowflake
- Build derived features such as per-group averages with pandas on Snowflake or SQL
- Choose between OSS, Snowflake ML preprocessors and Ray map_batches for a preprocessing job
- Scale and one-hot encode columns with a Snowflake ML Pipeline, and bin continuous values with WIDTH_BUCKET
Key concept
Lazy, pushed-down transformation — In Snowflake you describe a feature transformation on a DataFrame, and it runs as SQL inside Snowflake only when you trigger an action. That is why the same code can scale from a prototype to a production table without moving the data out.
1.Snowpark DataFrames and pandas on Snowflake
Almost all feature engineering in Snowflake starts with a DataFrame. A Snowpark DataFrame works more like a query than a container of rows. You build it in three steps: construct it from a source (a table, a staged file, local values or a SQL statement), describe the transformations (select, filter, sort, group), and then call an action such as collect() to execute it. Until you call that action, nothing runs.
Checkpoint 1 of 6· Check yourself
You chain select, filter and group_by calls on a Snowpark DataFrame built with session.table(...). When does Snowflake actually run the query?
Snowpark DataFrames are evaluated lazily. Transformations only build up the query, and an action like collect() executes it.
“In order to retrieve the data into the DataFrame, you must invoke a method that performs an action (for example, the collect() method).”Source: docs.snowflake.com
If your team already writes pandas, pandas on Snowflake (the Snowpark pandas API, built on Modin) lets you keep that syntax. You install snowflake-snowpark-python[modin] and change your imports. For large data, it translates your pandas operations into SQL and runs them in Snowflake.
import modin.pandas as pd
import snowflake.snowpark.modin.pluginFrom Snowpark Python 1.40.0, hybrid execution is on by default. pandas on Snowflake decides for itself whether an operation runs locally or in Snowflake, and df.get_backend() tells you which one it picked. A 10-million-row table read with pd.read_snowflake stays in Snowflake. A filtered aggregation that returns 7 rows can move to local pandas. Whichever backend runs it, the object is still a modin.pandas DataFrame, so code further down the pipeline doesn't need to change.
Checkpoint 2 of 6· Fill the gap
Which function creates a pandas on Snowflake DataFrame from an existing table?
# Create a Snowpark pandas DataFrame from existing Snowflake table
df = pd. ? ('SNOWFALL')pd.read_snowflake reads a Snowflake table, view, dynamic table or SQL query into a pandas on Snowflake DataFrame. session.table is the Snowpark DataFrame equivalent.
Source: docs.snowflake.comSources1
2.Derived features: aggregates such as average spend
Many columns can be used as features just as they are. Others become more useful once you derive something from them. Snowflake's own example is turning a timestamp into a day-of-week feature so a model can pick up weekly patterns. The documentation also names aggregating, differentiating and time-shifting as common transformations. A per-customer average spend is an aggregate of this kind: you group the transactions by the entity and take the mean of the amount.
In pandas on Snowflake you write that as an ordinary groupby. In the documentation's example, it computes the average snowfall for each location in a single expression. Because read_snowflake also accepts a SQL query, you can write the same aggregate in SQL and get a DataFrame back.
summary_df = pd.read_snowflake("SELECT LOCATION, AVG(SNOWFALL) AS avg_snowfall FROM SNOWFALL GROUP BY LOCATION")Checkpoint 3 of 6· Check yourself
An analyst has a SQL query that computes AVG(amount) per customer. They want the result as a pandas on Snowflake DataFrame without rewriting the query in pandas. What should they do?
read_snowflake accepts a SQL query as well as tables, views and dynamic tables, so you can move between SQL and pandas without copying the data out.
“You can also pass in a SQL query directly and get back a pandas on Snowflake DataFrame”Source: docs.snowflake.com
Sources2
3.Choosing where preprocessing runs
Once you have candidate features, preprocessing makes them ready for a model: scaling numeric columns and encoding categorical ones. Snowflake ML offers three ways to do this, and the right one depends mainly on data size and on how much custom logic you need.
| Aspect | OSS (including scikit-learn) | Snowflake ML preprocessors | Ray map_batches |
|---|---|---|---|
| Scale | Small & medium datasets | Large/distributed data | Large/distributed data |
| Execution Environment | In memory | Pushdown to the default warehouse that you’re using to run SQL queries | Across nodes in a compute pool |
| Compute Resources | Snowpark Container Services (Compute Pool) | Warehouse | Snowpark Container Services (Compute Pool) |
| Use Case Suitability | Quickly prototyping and experimentation | Production workflows with large datasets | Large data workflows that require custom resource controls |
The Snowflake ML preprocessors are a deliberate subset of scikit-learn's preprocessors that covers the most common cases. In exchange for that narrower set, they push the work down to a warehouse instead of pulling the data into memory. Ray map_batches is lazy too: nothing is processed until you materialize the dataset.
Checkpoint 4 of 6· Match them up
Match each scenario to the approach the documentation recommends
Tap a term, then the definition that fits it.
OSS runs in memory for small data. Snowflake ML preprocessors push down to a warehouse for large production data. Ray suits custom, resource-managed processing, especially of unstructured data.
“Ray map_batches - For highly customizable large-scale processing, especially with unstructured data”Source: docs.snowflake.com
Sources3
4.Scaling, normalization and one-hot encoding in a Snowflake ML Pipeline
The Snowflake ML preprocessors live in snowflake.ml.modeling.preprocessing, and they work on Snowpark DataFrames instead of local arrays. Each transformer names the columns it reads in input_cols and the columns it writes in output_cols. You chain transformers with snowflake.ml.modeling.pipeline.Pipeline, just as you would in scikit-learn. In the example below, StandardScaler scales AGE and INCOME, and OneHotEncoder turns the categorical CITY column into indicator columns.
# 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()Normalization. The only normalization these sources show is standardization: subtract the mean and divide by the standard deviation. StandardScaler does that inside Snowflake. The Ray example writes the same z-score formula by hand inside a batch function. Min-max scaling and other normalizers aren't covered in the documentation provided for this lesson, so look them up in the Snowflake ML preprocessing reference.
def preprocess_batch(batch: pd.DataFrame) -> pd.DataFrame:
batch['AGE_SCALED'] = (batch['age'] - batch['age'].mean()) / batch['age'].std()
return batchCheckpoint 5 of 6· Check yourself
In the Snowflake ML pipeline above, where does pipeline.fit_transform(df) compute the scaling statistics and the encoded columns?
Snowflake ML preprocessors push fitting and transforming down to the warehouse, so the data never has to fit in client memory.
“# Fit and transform data in Snowflake (distributed)”Source: docs.snowflake.com
Sources3
5.Binarizing: binning intervals, one-hot and label encoding
Binarizing means turning values into a small set of discrete codes. For binning continuous data into intervals, Snowflake SQL provides WIDTH_BUCKET. It divides a range into buckets of equal width and returns the number of the bucket each value falls into. Values below min_value get bucket 0. Values greater than or equal to max_value get num_buckets + 1, so outliers are labelled rather than dropped. If any input is NULL, the result is NULL.
WIDTH_BUCKET( <expr> , <min_value> , <max_value> , <num_buckets> )Checkpoint 6 of 6· Check yourself
You bin home prices with WIDTH_BUCKET(price, 200000, 600000, 4). A home sold for exactly 600000. Which bucket number is returned?
Values greater than or equal to max_value fall outside the range and get num_buckets + 1, which is 5 here.
“num_buckets + 1 if the expression is greater than or equal to max_value.”Source: docs.snowflake.com
One-hot encoding is the other form of binarizing covered here. OneHotEncoder (shown in the pipeline in the previous section, and in scikit-learn for the OSS route) replaces a categorical column with indicator columns. Label encoding, which maps each category to a single integer code, is not covered in the documentation provided for this lesson. Check the Snowflake ML preprocessing reference before relying on a particular class for it.
Sources4
Exam traps
Each one states something that sounds right. Open it to see what is actually true.
1.Snowflake ML preprocessors offer every transformer that scikit-learn does, just distributed.Why is that wrong?
They are a subset that covers the most common cases. For anything outside it, use OSS preprocessors on smaller data or custom Ray logic.
Covered in Choosing where preprocessing runs
2.For a large production table, running scikit-learn preprocessing is equivalent to using Snowflake ML preprocessors.Why is that wrong?
scikit-learn runs in memory and suits small or medium data. Snowflake ML preprocessors push down to the warehouse and are the recommended choice for large production workloads.
Covered in Scaling, normalization and one-hot encoding in a Snowflake ML Pipeline
Sources
Every claim above is drawn from one of these pages, quoted as it was written on the date shown.
- 1.
“When working with large datasets in Snowflake, it runs workloads natively in Snowflake through transpilation to SQL”
↩︎ Snowpark DataFrames and pandas on Snowflake“Starting with Snowpark Python version 1.40.0, hybrid execution is enabled by default when using pandas on Snowflake.”
↩︎ Snowpark DataFrames and pandas on Snowflake“Any DataFrames comprised of in-memory Python data will use the pandas backend”
↩︎ Prediction“You can also pass in a SQL query directly and get back a pandas on Snowflake DataFrame”
↩︎ Checkpoint - 2.
“Other common feature transformations involve aggregating, differentiating, or time-shifting data.”
↩︎ Derived features: aggregates such as average spend“For example, you might derive a day-of-week feature from a timestamp to allow the model to detect weekly patterns.”
↩︎ Derived features: aggregates such as average spend - 3.
“Ray map_batches uses lazy execution, meaning processing won’t happen until you materialize the datasets”
↩︎ Choosing where preprocessing runs“These preprocessors are pushed down to scale across warehouses.”
↩︎ Scaling, normalization and one-hot encoding in a Snowflake ML Pipeline“The Snowflake ML preprocessors are a subset of the preprocessors available in scikit-learn, but they cover the most common use cases.”
↩︎ Exam trap 1“Use Snowflake ML preprocessors for large datasets and production workloads.”
↩︎ Exam trap 2“Ray map_batches - For highly customizable large-scale processing, especially with unstructured data”
↩︎ Checkpoint“# Fit and transform data in Snowflake (distributed)”
↩︎ Checkpoint - 4.
“the histogram range is divided into intervals of identical size, and returns the bucket number into which the value of an expression falls”
↩︎ Binarizing: binning intervals, one-hot and label encoding“num_buckets + 1 if the expression is greater than or equal to max_value.”
↩︎ Checkpoint
Also cited
“A DataFrame represents a relational dataset that is evaluated lazily: it only executes when a specific action is triggered.”
↩︎ Key concept“In order to retrieve the data into the DataFrame, you must invoke a method that performs an action (for example, the collect() method).”
↩︎ Checkpoint