Start learning free

LESSON 29 OF 107 · DATA ENGINEERING: PIPELINES IN PYTHON

Extract, Transform, Load

Practice

A data pipeline moves rows from a source to a target and cleans them on the way. Here the source is one day's export of the shop's orders, orders/2026-05-02.csv, and the target is a file the analysts can query.

Data engineers split a pipeline into three jobs, ETL, each one a small function: extract reads the rows from the source, transform cleans them (a DataFrame in, a DataFrame out, no files), and load writes them to the target. In one long script, a new source or a new cleaning rule means digging through code that does everything at once. With three functions, each change touches only one of them, and you can try transform on a few hand-made rows.

The target is a Parquet file: a table format that stores each column with its type, compressed. A CSV file is only text, so every reader guesses the types again; a Parquet file gives numbers back as numbers, and tools like DuckDB read it fast. pandas writes one with df.to_parquet(path, index=False). index=False leaves out pandas' row labels: after a filter they have gaps, and they would land in the file as an extra column, __index_level_0__.

Here is a transform for another file, customers.csv, and the two lines that use it:

def clean_customers(df):
    readers = df[df["newsletter"] == "yes"]
    readers["big_spender"] = readers["spent"] > 400
    return readers

readers = clean_customers(pd.read_csv("customers.csv"))
readers.to_parquet("readers.parquet", index=False)

The starting code imports pandas and, at the bottom, already calls your functions: extract on orders/2026-05-02.csv (12 orders, 2 of them cancelled), transform on what it returns, and load into orders_2026-05-02.parquet. The check reads that file back with DuckDB and prints its rows and their total, then runs your three functions again on 05-01's file:

order_id | customer_id | product | quantity | unit_price | status | ordered_at | total
5012 | 78 | Plant | 2 | 15 | paid | 2026-05-02 10:06:00 | 30
5013 | 277 | Lamp | 2 | 29 | paid | 2026-05-02 12:01:00 | 58
…
5022 | 128 | Notebook | 2 | 7 | paid | 2026-05-02 20:39:00 | 14
(10 rows)
orders | total
10 | 382
(1 row)
The same three functions on orders/2026-05-01.csv:
orders | total
10 | 274
(1 row)

Your task: write extract(path), which returns the file at path read with pd.read_csv; transform(df), which keeps the rows whose status is "paid", adds a total column (quantity times unit_price) and returns them; and load(df, path), which writes df to path with to_parquet, without the index.


Assignment
Follow the Coding Tutorial to write extract, transform and load, one line at a time.


Hint
extract and transform must return their DataFrame: a function without a return gives back None, and the next function gets nothing to work on. load only writes the file, so it needs no return.


STEP 1 OF 8
    Ctrl + Enter to check