Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Expose merge threshold in python bindings. This makes it possible to merge
communities when they share many edges together after Leiden.
- Add NetworkX community detection bindings. This makes it possible to use pixelator-core
with NetworkX graphs.

### Changed

Expand Down
49 changes: 42 additions & 7 deletions packages/python_bindings/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# pixelator_core_py
# `pixelator_core` Python Bindings

[![Python versions](https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12%20%7C%203.13-blue)](https://github.com/PixelgenTechnologies/pixelator-core/actions/workflows/wheels.yml)

Expand All @@ -13,7 +13,8 @@ statistics and community detection algorithms for fast execution from Python.
- Leiden
- Hybrid FLP + Leiden flow (`run_hybrid_community_detection`)

> NB: for the sake of memory efficiency, all these bindings read and write the data from and to parquet files.
> NB: There are two main types of APIs provided by this package: parquet-backed APIs for workflows where
> memory-efficiency is a high priority and dedicated NetworkX APIs for in-memory graphs.

## Requirements

Expand Down Expand Up @@ -44,13 +45,10 @@ maturin build --release --out dist/
pip install dist/*.whl
```

## Quickstart
## Quick Start

```python
from pixelator_core import (
find_graph_statistics,
run_label_propagation,
run_leiden,
run_hybrid_community_detection,
)

Expand Down Expand Up @@ -80,9 +78,46 @@ print("Filtered edge list written to:", output_file)
print("Pre recovery nodes:", pre_recovery_stats.node_count)
```

### NetworkX usage

NetworkX APIs are provided for ease of use, for scenarios when the lowest possible
memory usage is not a priority.

```python
import networkx as nx
from pixelator_core import run_label_propagation_networkx, run_leiden_networkx

G = nx.Graph()
G.add_edge("cell_a", "cell_b", weight=2)
G.add_edge("cell_b", "cell_c")
G.add_node("isolated_cell")

flp_communities = run_label_propagation_networkx(G, epochs=2)
leiden_communities = run_leiden_networkx(
G,
resolution=1.0,
randomness=0.1,
seed=42,
)

# Both return:
# A list of disjoint sets (partition of G). Each set represents one community.
# All communities together contain all the nodes in G.
print(flp_communities)
print(leiden_communities)
```

Weight constraints for NetworkX APIs:
- `run_leiden_networkx` accepts non-negative integer-like weights and rejects fractional weights (for example `0.5`).
- `run_label_propagation_networkx` uses the same non-negative integer-like requirement and also requires weights to fit in `u8` (`0..=255`).

## Input and Output

- Input is expected to be an edge-list Parquet file compatible with `pixelator-core`.
- `find_graph_statistics`, `run_label_propagation`, `run_leiden`, and `run_hybrid_community_detection`
expect an edge-list Parquet file compatible with `pixelator-core`.
- `run_label_propagation_networkx` and `run_leiden_networkx` accept a `networkx.Graph` object
and return communities in-memory as a list of disjoint sets over original node labels.
- NetworkX edge weights for Leiden/FLP must be non-negative integer-like values; FLP additionally enforces the `u8` range (`0..=255`).
- `run_label_propagation` and `run_leiden` produce node-partition Parquet outputs.
- `run_hybrid_community_detection` produces a filtered edge-list Parquet output.
- Output paths are optional; defaults are used when omitted.
Expand Down
7 changes: 6 additions & 1 deletion packages/python_bindings/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,16 @@ readme = "README.md"
dependencies = []

[project.optional-dependencies]
dev = ["pytest>=8,<9", "pyarrow>=14", "maturin>=1,<2"]
dev = ["pytest>=8,<9", "pyarrow>=14", "maturin>=1,<2", "networkx>=3,<4"]

[tool.maturin]
module-name = "pixelator_core"

[build-system]
requires = ["maturin>=1.0,<2.0"]
build-backend = "maturin"

[dependency-groups]
dev = [
"ipykernel>=7.2.0",
]
Comment thread
johandahlberg marked this conversation as resolved.
Loading
Loading