Zarr would benefit from formal support of storing sparse arrays, though I'm not sure what this would look like and the process for getting there (e.g. placing the functionality in the core spec, creating a numcodec, and/or creating a ZEP to get there). But from some of the linked comments below it does seem very achievable.
If I'm wrong anywhere, please correct me. I'm not an expert on these packages.
Example use case: parallel processing of single cell RNA sequencing (scRNA-seq) data across a cluster.
Single cell sequencing data produces large arrays, often sparse, and often too large to store in memory. They would benefit from chunked, sparse, on-disk storage to empower chunked parallel processing on a Dask or Ray cluster in an efficient manner.
The current scRNA-seq analysis stack utilizes annData to wrap the data and scanpy to analyze it. annData was built upon HDF5 files but there has been an effort to utilize zarr and dask (with the current caveat seemingly that the central matrix is a dense np.ndarray due to zarr's limitation). scanpy doesn't fully support dask arrays at the moment (e.g. scverse/scanpy#2491) but since dask arrays follow the numpy API that shouldn't be hard to fix. Dask supports sparse arrays and Ray can be used as a plug-in scheduler for dask. In practice I've found anndata is able to load in a scipy sparse csr matrix from an hdf5 file.
Some previous efforts and discussions I've found
Proposed test code to set goalpost
We can try to implement all five of the array formats I've come across (included below), or stick to sparse.COO which follows the numpy API most completely, is more powerful by being n-dimensional, and is easy to chunk as the coordinates are exact (though less space efficient than csr or csc). Also sparse.COO is easily converted in memory to other sparse array types.
import zarr
import sparse
import numpy as np
# generate data
sparse_array = sparse.random((100,100), density=0.1, random_state=42)
sparse_arrays = [sparse_array, sparse.DOK.from_coo(sparse_array), sparse.GCXS.from_coo(sparse_array), sparse_array.tocsr(), sparse_array.tocsc()]
for sparse_array in sparse_arrays:
zarr.save("test.zarr", sparse_array, chunk=(20,20)) # write
read_array = zarr.load("test.zarr") # read
# test
assert type(read_array)==type(sparse_array)
assert read_array.shape==sparse_array.shape
if isinstance(read_array, np.ndarray):
assert (sparse_array==read_array).all() # np.ndarray doesn't implement .nnz() method
else:
assert (sparse_array!=read_array).nnz==0 # not all sparse formats implement .all() method
My ultimate use case
I'd like to analyze this dataset on a (local/remote) ray cluster using scanpy's default workflow at the start.
Some relevant stakeholders
@ivirshup, @alimanfoo, @rabernat, @jakirkham, @daletovar, @MSanKeys963
Zarr would benefit from formal support of storing sparse arrays, though I'm not sure what this would look like and the process for getting there (e.g. placing the functionality in the core spec, creating a numcodec, and/or creating a ZEP to get there). But from some of the linked comments below it does seem very achievable.
If I'm wrong anywhere, please correct me. I'm not an expert on these packages.
Example use case: parallel processing of single cell RNA sequencing (scRNA-seq) data across a cluster.
Single cell sequencing data produces large arrays, often sparse, and often too large to store in memory. They would benefit from chunked, sparse, on-disk storage to empower chunked parallel processing on a Dask or Ray cluster in an efficient manner.
The current scRNA-seq analysis stack utilizes annData to wrap the data and scanpy to analyze it. annData was built upon HDF5 files but there has been an effort to utilize zarr and dask (with the current caveat seemingly that the central matrix is a dense np.ndarray due to zarr's limitation). scanpy doesn't fully support dask arrays at the moment (e.g. scverse/scanpy#2491) but since dask arrays follow the numpy API that shouldn't be hard to fix. Dask supports sparse arrays and Ray can be used as a plug-in scheduler for dask. In practice I've found anndata is able to load in a scipy sparse csr matrix from an hdf5 file.
Some previous efforts and discussions I've found
meta_arrayargument to specify array typeProposed test code to set goalpost
We can try to implement all five of the array formats I've come across (included below), or stick to
sparse.COOwhich follows the numpy API most completely, is more powerful by being n-dimensional, and is easy to chunk as the coordinates are exact (though less space efficient than csr or csc). Alsosparse.COOis easily converted in memory to other sparse array types.My ultimate use case
I'd like to analyze this dataset on a (local/remote) ray cluster using scanpy's default workflow at the start.
Some relevant stakeholders
@ivirshup, @alimanfoo, @rabernat, @jakirkham, @daletovar, @MSanKeys963