Skip to main content

DuckPD mascot - a duck dressed as a panda

DuckPD

DuckPD is an experimental lazy DataFrame library with a pandas-shaped frontend and DuckDB as its execution engine.

[!WARNING] DuckPD is a work in progress and is not yet recommended for production-critical workloads. The API and supported pandas semantics may change between 0.x releases, and many pandas operations are intentionally unsupported. Validate results and resource behavior for each intended workload before adopting it.

DuckPD intentionally supports a small, explicit subset of pandas rather than silently falling back to materializing a complete pandas DataFrame. See the release policy for the pre-1.0 stability policy.

Current capabilities

  • Lazy pandas, Arrow, Parquet, DuckDB table, and read-only SQL sources.
  • Column selection, boolean filtering, arithmetic expressions, assign, sort_values, limit, and distinct/drop_duplicates deduplication.
  • Relational DataFrame joins (merge) supporting inner, left, right, outer, and cross with column collision suffix management.
  • Multi-DataFrame row-wise concatenation (duckpd.concat) with schema alignment and null-padding.
  • Vectorized .str (e.g. upper, lower, strip, len, contains, replace) and .dt (e.g. year, month, day, hour, minute, second, strftime, to_period) accessor pipelines.
  • Multi-column groupby() supporting eager and lazy agg(), sum(), mean(), min(), max(), std(), var(), and count().
  • Eager DataFrame and Series reductions: count, size, sum, mean, min, max, std, var, median, quantile, any, and all over numeric and boolean data, including skipna, min_count, and DataFrame numeric_only support.
  • Explicit lazy indexes with set_index()/reset_index() and source index=/order_by= declarations.
  • Explicit pandas collection, bounded head, Arrow tables and record batches, physical plan inspection (explain), and direct zero-copy Parquet writes.

Supported pandas API Coverage

DuckPD maps pandas semantics directly to DuckDB's vectorized analytical engine:

API Category Supported Methods & Operations Execution Model
I/O & Data Loading read_parquet(), read_sql(), from_pandas(), from_arrow(), sql(), connect() Lazy (scans metadata / registers source)
Transformations & Projections df[cols], df[bool_filter], assign(), sort_values(), limit(), drop_duplicates(), set_index(), reset_index() Lazy (appends to logical query graph)
Joins & Merges merge() (inner, left, right, outer, cross, custom suffixes) Lazy (relational hash join)
Concatenation duckpd.concat() (multi-frame row union, schema alignment, null padding) Lazy (union with projection padding)
String Accessor (.str) upper(), lower(), strip(), len(), startswith(), endswith(), contains(), replace() Lazy (DuckDB SQL functions)
Datetime Accessor (.dt) year, month, day, hour, minute, second, strftime(), to_period() Lazy (DuckDB timestamp extractors)
GroupBy Aggregations groupby().agg(), .sum(), .mean(), .min(), .max(), .std(), .var(), .count() (as_index=True/False) Lazy for .agg(), Eager for reductions
Statistical Reductions sum(), mean(), min(), max(), count(), size, std(), var(), median(), quantile(), any(), all() Eager (single aggregate SQL pushdown)
Collection & Output collect(), head(n), explain(), write_parquet(), to_arrow_table(), to_arrow_batches() Explicit Execution Boundary

Example

import duckpd as pd

orders = pd.read_parquet("orders/*.parquet")

result = (
    orders[orders["status"] == "paid"]
    .assign(net=lambda frame: frame["amount"] - frame["refund_amount"])
    .sort_values("net", ascending=False)[["order_id", "net"]]
    .limit(100)
)

print(result.explain())
preview = result.head(10)
result.write_parquet("largest-paid-orders.parquet")
pandas_result = result.collect()

Transformations above are lazy. explain(), head(), collect(), Arrow output, and file output are explicit execution boundaries. limit() stays lazy while head() returns a bounded pandas preview.

Demos

Interactive notebooks and small runnable programs are available in demo/:

  • demo/DuckPD_Quickstart.ipynb — 5-minute quickstart on the Goodreads Books dataset.
  • demo/DuckPD_Features_Walkthrough.ipynb — Deep dive into recent additions (remote cloud parquet, multi-table joins, .str/.dt accessors, duckpd.concat, statistical reductions, and multi-column groupbys) using the AlphaDojo stock news dataset (~3.9M rows).
uv run python demo/basic_pipeline.py
uv run python demo/parquet_pipeline.py
uv run python demo/reduction_pipeline.py
uv run python demo/generate_market_data.py
uv run python demo/market_data_demo.py

See the benchmark results for performance and memory comparisons between DuckPD and pandas across 100 MB, 1 GB, and 5 GB datasets.

Development

uv sync --frozen --group dev
make check
make build

GNU Make is optional. The equivalent commands are:

uv run pytest
uv run ruff check .
uv run ruff format --check .
uv run pyright
uv build

See the documentation index for the implementation roadmap, architecture decisions, benchmarks, research, and changelog.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

duckpd-0.0.5.tar.gz (1.5 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

duckpd-0.0.5-py3-none-any.whl (46.2 kB view details)

Uploaded Python 3

File details

Details for the file duckpd-0.0.5.tar.gz.

File metadata

  • Download URL: duckpd-0.0.5.tar.gz
  • Upload date:
  • Size: 1.5 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for duckpd-0.0.5.tar.gz
Algorithm Hash digest
SHA256 b1a6b4d18663650b6a7114c429acf04479acd55d11d1b51e4ad44f4b8ebd0985
MD5 c40d418b929056cd000d2655164ec41f
BLAKE2b-256 9c5681e3f77a511724f0c56d0fff5d124bc7929ec1b581013aa91a1d133c930f

See more details on using hashes here.

File details

Details for the file duckpd-0.0.5-py3-none-any.whl.

File metadata

  • Download URL: duckpd-0.0.5-py3-none-any.whl
  • Upload date:
  • Size: 46.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for duckpd-0.0.5-py3-none-any.whl
Algorithm Hash digest
SHA256 5799e69380bb2951bd386d550d946c124504b00e1e5803fc99c68b31d803cf20
MD5 1ff235739de22cad705c5e9c9d0ecbcb
BLAKE2b-256 249ff5ea53349bf88809c2b98d2f7fb1f4c7ed75aefaf2353eb6e960a075cf7f

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.4

2 files

0.1.3

2 files

0.1.2

2 files

0.1.1

2 files

0.0.7

2 files

This release

0.0.5 This release

2 files

0.0.4

2 files

0.0.3

2 files

0.0.2

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page