C.W.K.
Stream
Lesson 02 of 06 · published

The Modern Python Data Stack (April 2026)

~14 min · foundation, ecosystem, tools

Level 0Curious Reader
0 XP0/47 lessons0/11 achievements
0/120 XP to next level120 XP to go0% complete

One stack, glued by Apache Arrow

For most of the 2010s the Python data stack meant Pandas, sometimes NumPy, occasionally a database. That world is gone. The modern stack is multi-tool, polyglot, and held together by a single in-memory format: Apache Arrow. Knowing the cast is half of knowing what tool to reach for.

ToolVersion (Apr 2026)Role
Python3.13The language. Free-threaded build is experimental but landing.
NumPy2.4.4Fast n-dimensional arrays, the numerical bedrock under Pandas/PyArrow/sklearn/PyTorch.
Pandas3.0.2Tabular data: cleaning, grouping, joining, reshaping. Copy-on-Write is now the default; PyArrow-backed strings are widely used.
Polars1.39.3Rust-backed DataFrame library. Eager and lazy APIs. Handles bigger-than-memory data Pandas would choke on.
PyArrow23.0.1Apache Arrow in Python. The columnar in-memory format that lets Pandas, Polars, DuckDB, and storage talk without copies.
DuckDB1.5.2In-process SQL engine. Queries Parquet/Arrow/CSV/Pandas/Polars directly. "SQLite for analytics."
Parquetformat specColumnar binary file format. Compressed, statistics-rich, column-pruned reads. Default for analytics-at-rest.
Pandera0.24+Schema validation that integrates with Pandas and Polars.
Great Expectations1.xHeavier-weight expectation framework, good for cross-team data contracts.
Apache Airflow2.10Most-deployed orchestrator. DAGs of operators, scheduler, web UI.
Dagster1.10Asset-first orchestrator. Models data assets, not just tasks.
Prefect3.xPythonic flows. Lightweight, less infrastructure than Airflow.
dbt1.9SQL transformations as version-controlled code. Where modeling actually happens.
JupyterLab4.5+Interactive notebook IDE for exploration. Not a deployment target.

Arrow as the glue

Apache Arrow is a language-independent columnar memory format. The reason this matters in practice: when you read a Parquet file with PyArrow, hand the resulting Arrow Table to Pandas, query it with DuckDB, and pass the result to Polars — none of those steps copy the data. They share the same memory buffers. This is the difference between modern data work and the old serialize-deserialize-everywhere world.

You don't need to learn Arrow as a separate tool. You need to know that it's there, and that picking Arrow-aware libraries (Pandas 3.0, Polars, DuckDB, PyArrow) is what makes the stack feel fast.

Code

The whole stack in one snippet — Parquet → Arrow → DuckDB → Pandas, no copies·python
import pyarrow.parquet as pq
import duckdb

# Read a Parquet file as an Arrow Table — zero copy from disk
arrow_tbl = pq.read_table('orders.parquet')
print(f'Loaded {arrow_tbl.num_rows:,} rows, {arrow_tbl.num_columns} cols')

# Query that Arrow Table with SQL via DuckDB — also zero copy
result = duckdb.sql(
    '''
    SELECT date_trunc('month', order_date) AS month,
           SUM(amount_usd) AS revenue
    FROM arrow_tbl
    WHERE country = 'KR'
    GROUP BY 1
    ORDER BY 1
    '''
).to_df()                # convert only the result to a Pandas DataFrame

print(result.head())

External links

Exercise

In a fresh Python REPL, install pandas, pyarrow, and duckdb. Create any small Pandas DataFrame, write it to a Parquet file with df.to_parquet('demo.parquet'), then run duckdb.sql('SELECT * FROM "demo.parquet" LIMIT 5').to_df(). You just queried a file with SQL without spinning up a database server. Notice that.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.