Skip to main content

Efficient sparse matrix storage and retrieval using seekable Zstandard compression

Project description

zdata

Efficient sparse matrix storage and retrieval for large-scale datasets using seekable Zstandard compression.


What is zdata?

zdata is a Python library for storing and querying large sparse numerical matrices. While designed for single-cell RNA-seq data, it works with any sparse matrix that fits the (observations x features) pattern.

  • Store large datasets efficiently using block-based seekable Zstandard compression
  • Query specific rows or columns quickly without loading entire matrices into memory
  • Convert existing datasets from Zarr, H5AD (AnnData), or MTX+CSV into a fast, queryable format
  • Store any numerical type: uint8, uint16, uint32, uint64, int8, int16, int32, int64, float32, float64

Overview

zdata uses a custom on-disk format optimized for sparse data:

  • Block-compressed CSR layout -- data are grouped into small row blocks (default 16 rows per block) for fast access
  • Seekable Zstandard compression -- random access without decompressing entire files
  • Chunked storage -- large datasets split into multiple chunk files (default 8192 rows per file), scaling to millions of rows

Installation

From PyPI

pip install zdata-py

From source

Requires the Zstandard library for compiling the C tools:

git clone https://github.com/facebook/zstd.git
cd zstd && make lib && cd ..

git clone <repository-url> zdata
cd zdata
export ZSTD_BASE=/path/to/zstd
pip install -e .

The C tools (mtx_to_zdata, zdata_read) are compiled automatically during installation when ZSTD_BASE is set. Pre-compiled binaries are included in PyPI wheels.


Quick Start

Building a dataset

zdata can build from three input formats:

From Zarr or H5AD directories

from zdata import build_zdata_from_zarr

build_zdata_from_zarr(
    input_dir="/path/to/zarr_or_h5ad_files",
    output_name="my_dataset.zdata",
)

The input directory can contain .zarr directories, .h5/.hdf5/.h5ad files, or a mix of both.

From MTX+CSV directories

Each subdirectory should contain matrix.mtx, obs.csv, and var.csv:

from zdata import build_zdata_from_mtx_csv

build_zdata_from_mtx_csv(
    input_dir="/path/to/mtx_csv_dirs",
    output_name="my_dataset.zdata",
)

Specifying a data type

By default, values are stored as uint16 (suitable for raw scRNA-seq counts). For other data types:

build_zdata_from_zarr(
    input_dir="/path/to/data",
    output_name="my_dataset.zdata",
    dtype="float32",   # or: uint8, int32, float64, etc.
)

Supported dtypes: uint8, uint16, uint32, uint64, int8, int16, int32, int64, float32, float64.


Opening a dataset

from zdata import ZData

ds = ZData("my_dataset.zdata")
print(ds.shape)       # (n_cells, n_genes)
print(ds.obs.shape)   # observation metadata
print(ds.var.shape)   # variable metadata

Querying data

Row-based (cells)

# AnnData-like indexing
adata = ds[0:100]
adata = ds[[0, 10, 20]]

# Raw sparse matrix
csr = ds.read_rows_csr([0, 100, 200])

# Random sample
rows = ds.get_random_rows(50)

Column-based (genes)

Requires column-major (X_CM) data (built automatically):

matrix = ds["GAPDH"]
matrix = ds[["GAPDH", "PCNA", "TP53"]]

Gene list alignment

During dataset construction, genes are aligned to a standard reference list (default: files/2ks10c_genes.txt). To use your own gene list:

build_zdata_from_zarr(
    input_dir="/path/to/data",
    output_name="my_dataset.zdata",
    gene_list_path="/path/to/my_genes.txt",  # one gene name per line
)

Configuration

Settings can be changed at runtime, via environment variables, or with a context manager:

from zdata import settings

# Runtime
settings.block_rows = 32
settings.warn_on_large_queries = False

# Context manager
with settings.override(override_memory_check=True):
    ds.read_rows_csr(range(100000))
Setting Default Env var Description
max_rows_per_chunk 8192 ZDATA_MAX_ROWS_PER_CHUNK Max rows per chunk file
block_rows 16 ZDATA_BLOCK_ROWS Rows per compressed block
warn_on_large_queries True ZDATA_WARN_ON_LARGE_QUERIES Warn when querying >50k rows
large_query_threshold 50000 ZDATA_LARGE_QUERY_THRESHOLD Threshold for large query warning
override_memory_check False ZDATA_OVERRIDE_MEMORY_CHECK Bypass memory safety checks
max_workers None (auto) ZDATA_MAX_WORKERS Thread pool size for parallel reads

Command-Line Tools

After installation, these commands are available:

# Build from zarr/h5ad
zdata-build /path/to/data my_dataset.zdata

# Build from mtx+csv directories
zdata-build-mtx /path/to/mtx_dirs my_dataset.zdata

# Validate input directory
zdata-check /path/to/data

# Align genes and produce intermediate MTX files
zdata-align /path/to/data output_dir --gene-list genes.txt

All commands support --help for full options.


Memory estimation

estimate = ds.estimate_memory_requirements(row_indices=[0, 1, 2])
print(estimate["estimated_memory_gb"])

Output format

A .zdata directory contains:

my_dataset.zdata/
  metadata.json       # shape, chunking info, dtype
  obs.parquet         # observation metadata (cells)
  var.parquet         # variable metadata (genes)
  X_RM/               # row-major compressed chunks
    0.bin, 1.bin, ...
  X_CM/               # column-major compressed chunks (optional)
    0.bin, 1.bin, ...

Troubleshooting

C tools not found: Set ZSTD_BASE to your zstd source directory and reinstall:

export ZSTD_BASE=/path/to/zstd
pip install -e . --force-reinstall

Gene list not found: Pass gene_list_path= explicitly, or ensure files/2ks10c_genes.txt is present in the package.

Memory errors on large queries: Increase available memory, reduce query size, or set settings.override_memory_check = True.


Testing

pip install pytest pytest-xdist
export ZSTD_BASE=/path/to/zstd
pytest tests/ -v

License

MIT. See the LICENSE file for details.

Project details


Download files

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

Source Distribution

zdata_py-0.1.8.tar.gz (533.7 kB view details)

Uploaded Source

Built Distribution

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

zdata_py-0.1.8-py3-none-any.whl (533.3 kB view details)

Uploaded Python 3

File details

Details for the file zdata_py-0.1.8.tar.gz.

File metadata

  • Download URL: zdata_py-0.1.8.tar.gz
  • Upload date:
  • Size: 533.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for zdata_py-0.1.8.tar.gz
Algorithm Hash digest
SHA256 5b2ee7e062ec2d9e6ae872475b671d6292f41335193adddc11925d055d6c525b
MD5 5dc42ecbdd4fcc61ce99e26b82bc9737
BLAKE2b-256 a77994c430184883cf4736033cfd7c4e18573db32202aec4d732a37f5bf04ce6

See more details on using hashes here.

File details

Details for the file zdata_py-0.1.8-py3-none-any.whl.

File metadata

  • Download URL: zdata_py-0.1.8-py3-none-any.whl
  • Upload date:
  • Size: 533.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for zdata_py-0.1.8-py3-none-any.whl
Algorithm Hash digest
SHA256 ffe04032780b76bbf6faf178a9450fc590b750683a4f3068504004dc8dfbe965
MD5 17fe5935ab5a860a2242b778676f9911
BLAKE2b-256 4b1aaacab14f26ad6b4b050b8a8e8857afda541c1fc591775dacb1ac9ca33d07

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page