polars-gdx
Lazy, prefiltered Polars access to GAMS GDX files — no GAMS installation required.
scan_gdx(path, symbol=...)returns apl.LazyFrame; nothing is read untilcollect(), and column projection is pushed down via Polars' IO-source interface.read_gdx(...)is the eager convenience wrapper (scan_gdx(...).collect(), same arguments).- Predicates on key columns (
key_filter={dim_index: allowed_labels},filter(pl.col(key) == label)orfilter(pl.col(key).is_in(labels))) are folded into a native, index-based prefilter inside the Rust read loop, so unwanted records are never materialized — unlike the officialgamsapireader, which must load everything into pandas first. The prefilter runs inside a bulk C callback (gdxDataReadRawFastEx): one FFI crossing for the whole symbol, with early termination forhead(n). threads=(onscan_gdx/read_gdx) parallelises the raw read across independent file handles. With a first-dimension filter, each worker scans a contiguous range of the first key dimension and whole non-matching ranges are skipped without touching the file. Without one, the data section is split by file position at exact record boundaries: a cached restart-position index (one cheap sequential pass, built once per file+symbol) provides the boundaries, and each worker decodes only its own byte range. In both cases results are concatenated in range order so record order matches the serial read exactly, and any boundary/count mismatch falls back to a verified serial read.threads="auto"(recommended) uses all cores for symbols of 5M+ records and stays serial for smaller ones. Filters on non-leading dimensions still decode every record within each worker's range, but the decode is now spread across all workers instead of the single-threaded wall-time floor.read_domains(path, symbol=...)lists the unique labels actually used per index dimension in a single bulk C scan (gdxGetDomainElements) — the cost ofunique()over a key column without reading or materialising any records, valuable on very large symbols.- Under the hood: hand-written FFI to the vendored MIT-licensed GDX C library, extracted from lolow/gdxcomp, building on GAMS-dev/gdx.
Usage
import polars as pl
from polars_gdx import scan_gdx, list_symbols
list_symbols("trnsport.gdx").filter(pl.col("type") == "Param")
# lazy: nothing read yet
x = scan_gdx("trnsport.gdx", symbol="x")
# read only the seattle rows, skipping all others natively
x.filter(pl.col("dim_0") == "seattle").collect()
# eager convenience: read_gdx = scan_gdx(...).collect()
from polars_gdx import read_gdx
df = read_gdx("trnsport.gdx", symbol="x", key_filter={0: ["seattle"]})
# large symbols: parallel raw read across all cores
big = scan_gdx("huge.gdx", symbol="x", threads="auto")
# unique labels per index dimension without reading the records:
from polars_gdx import read_domains
read_domains("trnsport.gdx", symbol="x")
Label matching
Key labels (key_filter and filter(pl.col(key) == label) predicates) are matched case-insensitively (ASCII-folded), the way GAMS does — "SEATTLE" matches a stored "seattle". The labels in the produced frame always keep the file's original casing. For predicate filters whose label only differs in case from the stored one, the plugin deliberately skips the native prefilter and re-applies a case-folded predicate on the full read, because Polars' == is case-sensitive and would otherwise silently drop the rows.
File handle lifetime
scan_gdx keeps the GDX file open until the returned LazyFrame is collected and released (Polars may read the source more than once). Use read_gdx, or an explicit Reader with its close() / context-manager support, to release the handle eagerly — relevant on Windows, where an open handle locks the file.
Benchmark
vs gamsapi 54.5.0 (pandas-backed), on a 2M-record parameter (80 MB GDX); best of 5 runs. See benchmarks/bench_vs_gamsapi.py (run as a CI job on every push).
| Scenario | polars-gdx | gamsapi (pandas) |
|---|---|---|
| Full read (2M rows) | 0.128 s | 0.086 s |
filter(dim_0 == label) — 1000 of 2M rows |
0.059 s | 0.096 s¹ |
Explicit key_filter — 1000 rows |
0.058 s | — |
head(1000) of 2M rows |
0.001 s | 0.101 s¹ |
¹ gamsapi has no lazy loading or pushdown: it must materialize the whole symbol, then filter. The advantage of polars-gdx grows with predicate selectivity; head(n)/n_rows terminates the native read after n records.
Build
maturin develop --release # builds the vendored GDX C library + extension
pytest
Requires a C++17 compiler and CMake ≥ 3.5 at build time; runtime has no GAMS dependency.
Layout
crates/gdx-sys # raw FFI; builds vendored GDX-dev/gdx via CMake
crates/gdx # safe RAII wrapper (global lock; lazy UEL interning)
crates/polars-gdx # PyO3 extension: symbol listing + Arrow streaming with prefiltering
python/polars_gdx # Python layer: scan_gdx / list_symbols
Metadata
Release files for polars-gdx 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| polars_gdx-0.4.0.tar.gz | 2.3 MB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| polars_gdx-0.4.0-cp39-abi3-win_amd64.whl | CPython 3.9 | abi3 | Windows x86-64 | Details |
| polars_gdx-0.4.0-cp39-abi3-manylinux_2_28_x86_64.whl | CPython 3.9 | abi3 | Linux glibc 2.28+ x86-64 | Details |
| polars_gdx-0.4.0-cp39-abi3-manylinux_2_28_aarch64.whl | CPython 3.9 | abi3 | Linux glibc 2.28+ ARM64 | Details |
| polars_gdx-0.4.0-cp39-abi3-macosx_11_0_arm64.whl | CPython 3.9 | abi3 | macOS 11.0+ ARM64 | Details |
| polars_gdx-0.4.0-cp39-abi3-macosx_10_12_x86_64.whl | CPython 3.9 | abi3 | macOS 10.12+ x86-64 | Details |
Total release size: 5.5 MB
Release files / polars_gdx-0.4.0.tar.gz
| Download URL | polars_gdx-0.4.0.tar.gz |
|---|---|
| Size | 2.3 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
88b8f7e056e6b0e22af7d2274c69079c40dd9be0d0d852fce948adb610ee249a
|
|
BLAKE2b-256 checksum How to use checksums |
ff234303326696cc3e27f39a343162e3468499dfd5fce2a16634904286b011c9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency logRelease files / polars_gdx-0.4.0-cp39-abi3-win_amd64.whl
| Download URL | polars_gdx-0.4.0-cp39-abi3-win_amd64.whl |
|---|---|
| Size | 756.6 kB |
| Tags | CPython 3.9 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
d67e4efa683a7e5a51be4359b104b8d25d543dc7a667ff252e1f92859feeeaa1
|
|
BLAKE2b-256 checksum How to use checksums |
25e5ae2c63ffc163729089d9474bbbb2dd5f481f8f527dc91fe5de6747327d13
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency logRelease files / polars_gdx-0.4.0-cp39-abi3-manylinux_2_28_x86_64.whl
| Download URL | polars_gdx-0.4.0-cp39-abi3-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 640.0 kB |
| Tags | CPython 3.9 Linux glibc 2.28+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
2f1c92dcf713869c5d06161f60ddb5b80413a4b16a39bdd414108f827d61a21f
|
|
BLAKE2b-256 checksum How to use checksums |
305dc2697402027aa1d38e9a8b7892b4e4c048525458c41d3d740fc55185f51f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency logRelease files / polars_gdx-0.4.0-cp39-abi3-manylinux_2_28_aarch64.whl
| Download URL | polars_gdx-0.4.0-cp39-abi3-manylinux_2_28_aarch64.whl |
|---|---|
| Size | 607.6 kB |
| Tags | CPython 3.9 Linux glibc 2.28+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
e7ef764632c261b7d4a28b48081544a075c52cdc1f306e2d95145e0c32cb19aa
|
|
BLAKE2b-256 checksum How to use checksums |
e2d343fd209861c92fe0b3e86bbce2d76478e7e107d95988ce171c6b731479ed
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency logRelease files / polars_gdx-0.4.0-cp39-abi3-macosx_11_0_arm64.whl
| Download URL | polars_gdx-0.4.0-cp39-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 532.1 kB |
| Tags | CPython 3.9 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
ecdab946ebbc37267cfb768b185dd2d0824b4da7c3997dcc6459d5b6ddb256d3
|
|
BLAKE2b-256 checksum How to use checksums |
2c7281b0206b3c8a075b95cca4e8c6daab41c390603eb8b42c5ecd61eefb51b2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency logRelease files / polars_gdx-0.4.0-cp39-abi3-macosx_10_12_x86_64.whl
| Download URL | polars_gdx-0.4.0-cp39-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 575.4 kB |
| Tags | CPython 3.9 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
25e11c210211f4b9f757c63d6bbc98f9a448218f1b59328648865dc629c5ec7f
|
|
BLAKE2b-256 checksum How to use checksums |
6615fe5c7d673cd693adb310347e982c0b8f65c3f1536f7f4a87bec8cb9cad01
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency log