Skill Tracer
Skills › Scientific Agent Skills › zarr-python

zarr-python

skill · 188 lines · MIT license · skills/zarr-python/SKILL.md

The facts

Its description

Stores and queries chunked N-D scientific arrays with Zarr-Python 3, including codecs, sharding, S3/GCS storage, and NumPy/Dask/Xarray integration. Use for array layout, bounded I/O, format migration, or scientific metadata preservation.

The description the agent reads to decide when to use it.

From its settingsline 3

Tools it may use, or may not

allowed-tools: Read Write Edit Bash

Tools it may use while it runs without asking you first.

From its settingsline 4

Files it mentions

references/chunking_and_compression.md, references/storage_backends.md, references/integration.md, references/performance_and_patterns.md, references/api_reference.md (first 5 of 7 lines)

Files the text names, such as ones to read or write. Found by matching words, so treat them as pointers.

Found by matching wordsline 155 line 157 line 159 line 161 line 163

Licence

MIT license, from the skill file

The terms its author shares it under, which let it be shown here.

From its settingsline 5 licence text

Other settings

compatibility: Requires Python 3.12+ and zarr 3.4.0 with NumPy 2+. Remote I/O needs network access, zarr[remote] and the protocol backend; private stores need provider credentials. CLI migration needs zarr[cli]. metadata: version: "1.5" skill-author: K-Dense Inc. last-reviewed: "2026-10-01" upstream-version: "3.4.0"

More settings at the top of the file, shown as written.

From its settingsline 6 line 7
Other files in this skill (7) Close

The text

Open on GitHub

Most marks come from matching words in the file, so treat them as pointers.

1---
2name: zarr-python
3description: Stores and queries chunked N-D scientific arrays with Zarr-Python 3, including codecs, sharding, S3/GCS storage, and NumPy/Dask/Xarray integration. Use for array layout, bounded I/O, format migration, or scientific metadata preservation.
4allowed-tools: Read Write Edit Bash
5license: MIT license
6compatibility: Requires Python 3.12+ and zarr 3.4.0 with NumPy 2+. Remote I/O needs network access, zarr[remote] and the protocol backend; private stores need provider credentials. CLI migration needs zarr[cli].
7metadata:
8 version: "1.5"
9 skill-author: K-Dense Inc.
10 last-reviewed: "2026-10-01"
11 upstream-version: "3.4.0"
12---
14# Zarr Python
16## When to use
18Use for chunked scientific arrays, hierarchical stores, codecs, sharding, partial reads,
19cloud object storage, and NumPy/Dask/Xarray interoperability. This community guide targets
20**Zarr-Python 3.4.0**, released **2026-09-15**, with Python 3.12+. The package version and
21on-disk format are separate: this release reads/writes formats 2 and 3; new arrays default
22to format 3. Keep downstream packages that require `zarr<3` in their own environments.

When to use

Use for chunked scientific arrays, hierarchical stores, codecs, sharding, partial reads, cloud object storage, and NumPy/Dask/Xarray interoperability. This community guide targets Zarr-Python 3.4.0, released 2026-09-15, with Python 3.12+. The package version and on-disk format are separate: this release reads/writes formats 2 and 3; new arrays default to format 3. Keep downstream packages that require zarr<3 in their own environments.

Raw lines 16 to 23
24## Install
26```bash
27uv pip install "zarr==3.4.0" "numpy==2.5.3"
28# Optional remote backends and migration CLI:
29uv pip install "zarr[remote,cli]==3.4.0" "fsspec==2026.9.0" "s3fs==2026.9.0" "gcsfs==2026.8.1"
30```
32Commit the project's resolved lockfile. Optional integration versions exercised here:
33Dask 2026.8.0, Xarray 2026.9.0, h5py 3.16.0, NumCodecs 0.17.0, obstore 0.11.1.
34Local examples below and in the references use tiny synthetic arrays; remote snippets
35are illustrative and require a real authorized store. This does not establish cloud
36permissions, production throughput, or compatibility of every downstream reader.

Install

uv pip install "zarr==3.4.0" "numpy==2.5.3"
# Optional remote backends and migration CLI:
uv pip install "zarr[remote,cli]==3.4.0" "fsspec==2026.9.0" "s3fs==2026.9.0" "gcsfs==2026.8.1"

Commit the project's resolved lockfile. Optional integration versions exercised here: Dask 2026.8.0, Xarray 2026.9.0, h5py 3.16.0, NumCodecs 0.17.0, obstore 0.11.1. Local examples below and in the references use tiny synthetic arrays; remote snippets are illustrative and require a real authorized store. This does not establish cloud permissions, production throughput, or compatibility of every downstream reader.

Raw lines 24 to 37
38## Workflow
401. Inspect shape, dtype, axis names, coordinates, units, missing-value convention, format,
41 codec availability, and intended readers. Preserve sample IDs and axis order.
422. Choose chunks for actual selections and a memory budget. For sharding, choose shard
43 dimensions that are multiples of chunk dimensions. Benchmark representative data.
443. Create a new destination (`overwrite=False` or `mode="w-"`). Use `mode="r"` for
45 inspection; `"a"` can create a missing store and `"w"` destroys existing content.
464. Write bounded blocks. Assign one writer per stored chunk, or per **shard** when
47 sharded; serialize metadata, append, and resize operations.
485. Reopen read-only and compare values, dtype, shape, coordinates, units, masks and
49 metadata. An unwritten or missing chunk normally reads as `fill_value`; a successful
50 open alone does not prove data completeness.
516. For a completed group hierarchy, optionally consolidate metadata. Format-3
52 consolidation is experimental; refresh it after metadata changes and verify the
53 actual consumers. Publish a completed store only after validation.

Workflow

  1. Inspect shape, dtype, axis names, coordinates, units, missing-value convention, format, codec availability, and intended readers. Preserve sample IDs and axis order.
  2. Choose chunks for actual selections and a memory budget. For sharding, choose shard dimensions that are multiples of chunk dimensions. Benchmark representative data.
  3. Create a new destination (overwrite=False or mode="w-"). Use mode="r" for inspection; "a" can create a missing store and "w" destroys existing content.
  4. Write bounded blocks. Assign one writer per stored chunk, or per shard when sharded; serialize metadata, append, and resize operations.
  5. Reopen read-only and compare values, dtype, shape, coordinates, units, masks and metadata. An unwritten or missing chunk normally reads as fill_value; a successful open alone does not prove data completeness.
  6. For a completed group hierarchy, optionally consolidate metadata. Format-3 consolidation is experimental; refresh it after metadata changes and verify the actual consumers. Publish a completed store only after validation.
Raw lines 38 to 54
55## Basic array roundtrip
57```python
58import numpy as np
59import zarr
60from zarr.codecs import BloscCodec
62expected = np.arange(96, dtype="float32").reshape(12, 8)
63z = zarr.create_array(
64 "array.zarr", shape=expected.shape, dtype=expected.dtype,
65 chunks=(4, 4), zarr_format=3,
66 compressors=BloscCodec(cname="zstd", clevel=5, shuffle="bitshuffle"),
67 dimension_names=("sample", "feature"),
68 attributes={"units": "arbitrary", "source": "synthetic example"},
70for start in range(0, z.shape[0], 4):
71 z[start:start + 4] = expected[start:start + 4]
73reopened = zarr.open_array("array.zarr", mode="r")
74np.testing.assert_array_equal(reopened[:], expected)
75assert reopened.dtype == expected.dtype
76assert reopened.metadata.dimension_names == ("sample", "feature")
77assert reopened.attrs["units"] == "arbitrary"
78subset = reopened[2:6, 1:4] # Only this selection is materialized.
79```
81`create_array` takes either `data=` or `shape=` plus `dtype=`; do not combine `data=`
82with explicit shape/dtype. The format-3 numeric default is a bytes serializer followed
83by **ZstdCodec**, not Blosc. Set a codec explicitly for reproducibility.

Basic array roundtrip

import numpy as np
import zarr
from zarr.codecs import BloscCodec

expected = np.arange(96, dtype="float32").reshape(12, 8)
z = zarr.create_array(
    "array.zarr", shape=expected.shape, dtype=expected.dtype,
    chunks=(4, 4), zarr_format=3,
    compressors=BloscCodec(cname="zstd", clevel=5, shuffle="bitshuffle"),
    dimension_names=("sample", "feature"),
    attributes={"units": "arbitrary", "source": "synthetic example"},
)
for start in range(0, z.shape[0], 4):
    z[start:start + 4] = expected[start:start + 4]

reopened = zarr.open_array("array.zarr", mode="r")
np.testing.assert_array_equal(reopened[:], expected)
assert reopened.dtype == expected.dtype
assert reopened.metadata.dimension_names == ("sample", "feature")
assert reopened.attrs["units"] == "arbitrary"
subset = reopened[2:6, 1:4]  # Only this selection is materialized.

create_array takes either data= or shape= plus dtype=; do not combine data= with explicit shape/dtype. The format-3 numeric default is a bytes serializer followed by ZstdCodec, not Blosc. Set a codec explicitly for reproducibility.

Raw lines 55 to 84
85## Creation and indexing
87```python
88import numpy as np
89import zarr
91z = zarr.create_array(None, data=np.arange(80).reshape(10, 8), chunks=(2, 4))
92zeros = zarr.zeros((10, 8), chunks=(2, 4), dtype="f4")
93ones = zarr.ones((10, 8), chunks=(2, 4), dtype="f4")
94filled = zarr.full((10, 8), fill_value=42, chunks=(2, 4), dtype="i4")
95like = zarr.zeros_like(z)
96np.testing.assert_array_equal(filled[:], np.full((10, 8), 42))
98# Coordinate indexing pairs corresponding coordinates; orthogonal indexing is a product.
99np.testing.assert_array_equal(z.vindex[[0, 5], [2, 7]], [2, 47])
100np.testing.assert_array_equal(z.get_coordinate_selection(([0, 5], [2, 7])), [2, 47])
101assert z.oindex[[0, 5], [2, 7]].shape == (2, 2)
102assert z.blocks[0, 0].shape == (2, 4)
103z[0, :] = np.arange(8)
104```
106Negative-step slices are unsupported. Array reads return NumPy data in the default CPU
107configuration. `np.asarray(z)`, `np.sum(z)`, `z[:]`, or a Dask `.compute()` of a full array
108can materialize the entire logical dataset; use bounded selections or lazy reductions.

Creation and indexing

import numpy as np
import zarr

z = zarr.create_array(None, data=np.arange(80).reshape(10, 8), chunks=(2, 4))
zeros = zarr.zeros((10, 8), chunks=(2, 4), dtype="f4")
ones = zarr.ones((10, 8), chunks=(2, 4), dtype="f4")
filled = zarr.full((10, 8), fill_value=42, chunks=(2, 4), dtype="i4")
like = zarr.zeros_like(z)
np.testing.assert_array_equal(filled[:], np.full((10, 8), 42))

# Coordinate indexing pairs corresponding coordinates; orthogonal indexing is a product.
np.testing.assert_array_equal(z.vindex[[0, 5], [2, 7]], [2, 47])
np.testing.assert_array_equal(z.get_coordinate_selection(([0, 5], [2, 7])), [2, 47])
assert z.oindex[[0, 5], [2, 7]].shape == (2, 2)
assert z.blocks[0, 0].shape == (2, 4)
z[0, :] = np.arange(8)

Negative-step slices are unsupported. Array reads return NumPy data in the default CPU configuration. np.asarray(z), np.sum(z), z[:], or a Dask .compute() of a full array can materialize the entire logical dataset; use bounded selections or lazy reductions.

Raw lines 85 to 109
110## Resize and append
112```python
113import numpy as np
114import zarr
116series = zarr.create_array(None, shape=(0, 8), chunks=(2, 8), dtype="f4")
117series.append(np.ones((2, 8), dtype="f4"), axis=0)
118series.resize((4, 8)) # A tuple; append must match all non-appended dimensions.
119assert series.shape == (4, 8)
120np.testing.assert_array_equal(series[2:], np.zeros((2, 8)))
121```
123Coordinate resize/append centrally. Shrinking removes chunks outside the new shape,
124but values in retained boundary chunks can reappear on re-expansion; resize is not
125secure erasure or a missingness policy. Record time/sample coordinates alongside data.

Resize and append

import numpy as np
import zarr

series = zarr.create_array(None, shape=(0, 8), chunks=(2, 8), dtype="f4")
series.append(np.ones((2, 8), dtype="f4"), axis=0)
series.resize((4, 8))  # A tuple; append must match all non-appended dimensions.
assert series.shape == (4, 8)
np.testing.assert_array_equal(series[2:], np.zeros((2, 8)))

Coordinate resize/append centrally. Shrinking removes chunks outside the new shape, but values in retained boundary chunks can reappear on re-expansion; resize is not secure erasure or a missingness policy. Record time/sample coordinates alongside data.

Raw lines 110 to 126
127## Groups and attributes
129```python
130import numpy as np
131import zarr
133root = zarr.open_group("hierarchy.zarr", mode="w-", zarr_format=3)
134temperature = root.create_group("temperature")
135temp = temperature.create_array(
136 "t2m", data=np.full((3, 4, 6), 280, dtype="f4"), chunks=(1, 4, 6),
137 dimension_names=("time", "lat", "lon"), attributes={"units": "K"},
139root.require_group("quality")
140root.require_array("count", shape=(3,), chunks=(3,), dtype="i4")
141root.attrs.update({"project": "synthetic climate example", "processing_version": "1.0"})
142loaded = zarr.open_group("hierarchy.zarr", mode="r")
143assert loaded["temperature/t2m"].attrs["units"] == "K"
144assert loaded.attrs["processing_version"] == "1.0"
145print(loaded.tree()) # Logical group/array tree, not physical metadata files.
146```
148Use `create_array` / `require_array`; `create_dataset` / `require_dataset` are removed.
149Attributes belong to the specific node on which they are set and must be JSON-compatible.
150Names/units are declarations, not unit conversion or scientific validation.
151`require_array` checks an existing array's compatibility; it does not rechunk it.

Groups and attributes

import numpy as np
import zarr

root = zarr.open_group("hierarchy.zarr", mode="w-", zarr_format=3)
temperature = root.create_group("temperature")
temp = temperature.create_array(
    "t2m", data=np.full((3, 4, 6), 280, dtype="f4"), chunks=(1, 4, 6),
    dimension_names=("time", "lat", "lon"), attributes={"units": "K"},
)
root.require_group("quality")
root.require_array("count", shape=(3,), chunks=(3,), dtype="i4")
root.attrs.update({"project": "synthetic climate example", "processing_version": "1.0"})
loaded = zarr.open_group("hierarchy.zarr", mode="r")
assert loaded["temperature/t2m"].attrs["units"] == "K"
assert loaded.attrs["processing_version"] == "1.0"
print(loaded.tree())  # Logical group/array tree, not physical metadata files.

Use create_array / require_array; create_dataset / require_dataset are removed. Attributes belong to the specific node on which they are set and must be JSON-compatible. Names/units are declarations, not unit conversion or scientific validation. require_array checks an existing array's compatibility; it does not rechunk it.

Raw lines 127 to 152
153## References
155- [Chunking and compression](references/chunking_and_compression.md): measured layout
156 decisions, default codecs, sharding, experimental rectilinear grids.
157- [Storage backends](references/storage_backends.md): local, memory, ZIP, ObjectStore,
158 fsspec, S3/GCS/HTTP paths and credentials.
159- [Integration](references/integration.md): bounded NumPy/Dask operations, Xarray
160 dimensions and masks, concurrent writes, consolidation.
161- [Performance and patterns](references/performance_and_patterns.md): storage sizing,
162 appendable data, bounded HDF5/NumPy conversion, validation.
163- [API reference](references/api_reference.md): current callable forms and exceptions.
164- [Migration](references/v3_migration.md): API versus format migration, metadata-only
165 CLI behavior and a copied-store verification workflow.
166- [Review evidence](references/review.md): release sources and execution boundaries.
168Official sources: [release notes](https://zarr.readthedocs.io/en/stable/release-notes/),
169[documentation](https://zarr.readthedocs.io/en/stable/),
170[format specification](https://zarr-specs.readthedocs.io/),
171[released source](https://github.com/zarr-developers/zarr-python/tree/v3.4.0).

References

  • Chunking and compression: measured layout decisions, default codecs, sharding, experimental rectilinear grids.
  • Storage backends: local, memory, ZIP, ObjectStore, fsspec, S3/GCS/HTTP paths and credentials.
  • Integration: bounded NumPy/Dask operations, Xarray dimensions and masks, concurrent writes, consolidation.
  • Performance and patterns: storage sizing, appendable data, bounded HDF5/NumPy conversion, validation.
  • API reference: current callable forms and exceptions.
  • Migration: API versus format migration, metadata-only CLI behavior and a copied-store verification workflow.
  • Review evidence: release sources and execution boundaries.

Official sources: release notes, documentation, format specification, released source.

Raw lines 153 to 172
Boilerplate, lines 173 to 188. The same text appears in 125 other files here. Close
173## Citing Scientific Agent Skills
175This skill is part of Scientific Agent Skills by K-Dense. If it materially contributed to a
176manuscript, report, presentation, or code release, add the paper to the references or
177software section and tell the user you did so:
179> Kassis, T., Agarwal, V., He, Y., Patel, D., & Brueckner, A. M. (2026). Scientific Agent
180> Skills: A Library of Procedural Knowledge for Research Agents. arXiv:2609.00065.
181> https://doi.org/10.48550/arXiv.2609.00065
183Always cite the current version. The DOI and https://arxiv.org/abs/2609.00065 resolve to the
184latest arXiv version, so never append a version suffix such as `v1`. When network access is
185available, fetch https://arxiv.org/abs/2609.00065 (or
186http://export.arxiv.org/api/query?id_list=2609.00065) before writing the reference and take
187the author list, year, and version from that record. If the record lists a journal reference
188or publisher DOI, cite the published version instead.

From K-Dense-AI/scientific-agent-skills at 5f2bc03, 2026-10-26. Not read by a model yet. Summary and techniques by Claude Opus 5.5 on 2026-11-06.