Skip to main content

PyFgsea: GSEA in Python and Rust

PyFgsea runs preranked Gene Set Enrichment Analysis (GSEA) from Python with a Rust numerical core. It supports single analyses and rolling-window pathway analysis along an ordered trajectory.

The current stable release is 0.2.0.

Features

  • Rust-backed enrichment-score and null-estimation kernels.
  • mode="aligned" for comparisons with R fgseaMultilevel under an explicit parameter contract.
  • Deterministic gene-ID tie ordering and exact pathway-size nulls.
  • Explicit ES, NES, p-value, tail-error, unresolved, and failure diagnostics.
  • Rolling-window GSEA for single-cell or other ordered trajectories.
  • pandas-friendly input and output.

Installation

PyFgsea requires Python 3.9 or newer. Building from source also requires a Rust toolchain.

git clone https://github.com/shayuanxukuang/pyfgsea.git
cd pyfgsea
python -m pip install --upgrade pip maturin
python -m pip install .

Install trajectory and plotting dependencies only when needed:

python -m pip install ".[trajectory]"

For Rust development:

maturin develop --release --locked

Quick start

import pandas as pd
import pyfgsea

ranks = pd.DataFrame(
    {
        "gene_name": ["GeneA", "GeneB", "GeneC", "GeneD", "GeneE"],
        "score": [2.5, 1.8, 0.5, -0.2, -1.5],
    }
)

pathways = {
    "Pathway_1": ["GeneA", "GeneB"],
    "Pathway_2": ["GeneD", "GeneE"],
}

result = pyfgsea.run_gsea(
    data=ranks,
    gmt=pathways,
    gene_col="gene_name",
    score_col="score",
    min_size=1,
    max_size=500,
    nperm_nes=100,
)

print(result[["Pathway", "NES", "P-value", "padj", "ES", "status"]])

Inputs

  • A DataFrame must contain a gene column and a ranking-score column. Select them with gene_col and score_col.
  • A Series uses its index as gene identifiers and its values as scores.
  • dedup_genes="max_abs", the default, keeps the duplicate entry with the largest absolute score.
  • Pathways may be supplied as a mapping from pathway names to gene lists.

Outputs

The main result columns are:

  • Pathway, Size, ES, NES, P-value, and padj;
  • log2err, log_pval, n_levels, and pval_capped;
  • status and termination_reason for resolved, unresolved, and failed rows;
  • observed_pathway_size, null_curve_size, size_binned, and approximate;
  • ranking_hash and algorithm_revision for provenance.

Pathways with unresolved or failed estimates remain visible in the output. They must not be silently removed before reporting or comparison.

Aligned and fast modes

mode="aligned" is the default. It uses exact pathway sizes (bin_width=0) and is the mode intended for the current R fgsea 1.38.0 conformance lane.

mode="fast" starts with an empirical precheck. A shallow tail may return the simple estimate; a deeper tail proceeds to the multilevel compound ruler. Fast results are marked approximate=True, and termination_reason records the route. Do not report fast-mode output as aligned-mode output.

The deprecated score_type="two_sided_abs" and low-level empirical tail helpers remain available for bounded compatibility work. They are approximate and are not equivalent to R fgseaMultilevel(scoreType="std").

Rolling-window trajectory GSEA

PyFgsea can rank genes and run GSEA repeatedly across overlapping windows of cells ordered by pseudotime. The default ranking statistic is:

mean(expression in window) - mean(expression outside window)

Run the included synthetic example:

python examples/trajectory_demo.py \
  --adata repro/data/toy_trajectory.h5ad \
  --gmt repro/data/toy_pathways.gmt \
  --pseudotime-key dpt_pseudotime \
  --window-size 100 \
  --step 50 \
  --outdir results/

The example writes:

  • results/trajectory_demo.png;
  • results/trajectory_gsea_table.tsv.

Trajectory defaults are window_size=500, step=50, min_size=15, max_size=500, nperm_nes=2000, score_type="std", exact pathway sizes, NES caching off, and seed=42. The Python API does not currently expose an n_threads keyword.

Reproducing the paper

The paper used PyFgsea 0.1.4 with R fgsea 1.32.2. Current comparisons use PyFgsea 0.2.0 with R fgsea 1.38.0. Keep these two reference lanes separate.

See:

Current limitations

  • The formal Figure 1 comparison covers the publication input and a separate tie-heavy sensitivity case; it is not a universal equivalence claim.
  • Figure 2 is a descriptive analysis of a processed, mixed-assignment subset; it is not a control-versus-mutant comparison.
  • Fast mode and the legacy empirical helpers are approximate.
  • Runtime and peak-memory values depend on the recorded hardware and software environment.

Citation

If you use PyFgsea in academic work, cite:

Wang K, Shi H. PyFgsea: a Rust-powered, fgseaMultilevel-aligned GSEA framework with rolling-window enrichment along single-cell trajectories. Bioinformatics. 2026;42(5):btag257. doi:10.1093/bioinformatics/btag257.

License

MIT License. See LICENSE.

Metadata

Release files for pyfgsea 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pyfgsea 0.2.0
File Size Uploaded
pyfgsea-0.2.0.tar.gz 70.8 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for pyfgsea 0.2.0
File Interpreter ABI Platform
pyfgsea-0.2.0-cp38-abi3-win_amd64.whl CPython 3.8 abi3 Windows x86-64 Details
pyfgsea-0.2.0-cp38-abi3-manylinux_2_34_x86_64.whl CPython 3.8 abi3 Linux glibc 2.34+ x86-64 Details
pyfgsea-0.2.0-cp38-abi3-macosx_11_0_arm64.whl CPython 3.8 abi3 macOS 11.0+ ARM64 Details

Total release size: 1.3 MB

Release files / pyfgsea-0.2.0.tar.gz

Download URL pyfgsea-0.2.0.tar.gz
Size 70.8 kB
Tags Source
SHA-256 checksum
How to use checksums
d1a9562939a8ef20079f3e0258cf6312e5f1a63befb5e02e5eeaad060194ad16
BLAKE2b-256 checksum
How to use checksums
b9ea5ba9eec2d4ca5c6a4d6bbabcd078cda28efb2f7aa0780bd4493314304dee
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release files / pyfgsea-0.2.0-cp38-abi3-win_amd64.whl

Download URL pyfgsea-0.2.0-cp38-abi3-win_amd64.whl
Size 317.9 kB
Tags CPython 3.8 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
35af0dffa6ddc7b3d00127184378d5dab6799dddaf9f93b824ac802a9554f61f
BLAKE2b-256 checksum
How to use checksums
726b139499829cd3278c9729ccf4461d100aac826e765b608eff53b0a1e2a07c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release files / pyfgsea-0.2.0-cp38-abi3-manylinux_2_34_x86_64.whl

Download URL pyfgsea-0.2.0-cp38-abi3-manylinux_2_34_x86_64.whl
Size 503.5 kB
Tags CPython 3.8 Linux glibc 2.34+ x86-64 abi3
SHA-256 checksum
How to use checksums
b167f4add33261668dca21ba667119a0255b95f553249e0cbc342de5b7441fdb
BLAKE2b-256 checksum
How to use checksums
a7370f49d41ea9d2bed1a58028834277e4727c89cb33a027556d0cfda7b9433a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release files / pyfgsea-0.2.0-cp38-abi3-macosx_11_0_arm64.whl

Download URL pyfgsea-0.2.0-cp38-abi3-macosx_11_0_arm64.whl
Size 436.1 kB
Tags CPython 3.8 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
16cfd36510352f2c1e381c27589af5459e294c0d52e06667704b7b5aadfdade3
BLAKE2b-256 checksum
How to use checksums
e0e524edc913cd506876a83c06004a2c6284b5ae2a7282ef1afc85467d654524
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release history Release notifications | RSS feed

This release

0.2.0 This release

4 release files

0.1.4

4 release 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