# Zarr Chunked Arrays

> 当需要为超大 N 维科学数组（气候/遥感/影像）做分块、压缩与并行读写，或要把数据放到 S3/GCS 做云原生工作流，或与 NumPy/Dask/Xarray 互通时使用；做 Zarr 3 数组/组的创建、分块与分片策略选型、压缩编解码配置、云端 fsspec 存储与元数据合并，产出 .zarr 存储与读写代码；不适用于纯内存中小型数组（直接用 NumPy）或关系/表格数据（用 Parquet/数据库）。触发词：zarr、分块数组、云端 N 维数组、chunks 分片 sharding、Xarray Dask Zarr

- Skill: `findscripter/zarr-chunked-arrays` (Agent Skill)
- Install (CLI): `npx skillmds@latest add findscripter/zarr-chunked-arrays`
- Raw SKILL.md: https://api.skillmd.com/api/skills/findscripter/zarr-chunked-arrays/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Data & Analytics
- License: MIT
- Author: findscripter (https://skillmd.com/u/findscripter)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/findscripter/zarr-chunked-arrays

---

# Zarr 云端分块 N 维数组

## 何时使用

- 存储/处理超大 N 维数组（气候、遥感、显微影像、基因组等），需要分块（chunking）+ 按块压缩 + 并行 I/O。
- 云原生工作流：把数组放到 S3/GCS/HTTP，通过 fsspec 直接读写。
- 需与 NumPy / Dask / Xarray 无缝互通，或处理超出内存（larger-than-RAM）的数据集。

不该用的边界：
- 纯内存中小型数组、一次性计算 —— 直接用 NumPy 即可，别引入 Zarr 开销。
- 关系型/表格数据 —— 用 Parquet、DuckDB 或数据库；Zarr 是为稠密 N 维网格设计的。
- 频繁随机小写、强一致多写场景 —— Zarr 3 尚未移植 `synchronizer`，需自行设计无重叠写入或外部锁。
- 任务与上述范围不明确匹配、缺少输入/权限/成功标准时，先停下澄清；产物不替代针对具体环境的校验与评审。

## 步骤 / 指令

1. 安装（需 Python 3.12+）：`uv pip install "zarr>=3.2,<4"`；云端再装 `uv pip install "zarr[remote]" s3fs gcsfs`。仅在被迫留在 Zarr v2 时用 `zarr==2.*`。
2. 选存储后端：本地 `LocalStore`（字符串路径即可）、临时 `MemoryStore`、打包 `ZipStore`（用完必须 `store.close()`）、云端用 `s3://`/`gs://` URI 或 `FsspecStore.from_url(...)`。
3. 建数组：`zarr.create_array(store=..., shape=..., chunks=..., dtype=...)`；或便捷函数 `zarr.zeros/ones/full/array/zeros_like`。新数组默认 Zarr format 3，需旧版互通时传 `zarr_format=2`。
4. 定分块（性能关键）：目标每块 ~1-10MB；块形状对齐访问模式 —— 常按行读则块跨列、常按列读则块跨行、随机访问用方块。整块须能装入内存（压缩时）。
5. 海量小块时用分片：`shards=(...)` 把多个 chunk 聚成一个存储对象，减少文件/对象数（整个 shard 须能入内存）。
6. 配压缩：默认 Blosc+Zstd；通过 `codecs=[BloscCodec(...)/GzipCodec(...)/BytesCodec()]` 调整或关闭。数值数据开 `shuffle` 提升压缩比。
7. 读写：NumPy 式索引 `z[i:j, :]`；高级索引 `z.vindex`/`z.oindex`/`z.blocks`；扩容 `z.resize((...))`，追加 `z.append(arr, axis=0)`。
8. 组织层级：`zarr.group()` 建组，组内 `create_array`/`require_array`（v3 已移除 h5py 风格的 `create_dataset`）；`root.tree()` 查看结构。
9. 云端/多数组提速：写完 `zarr.consolidate_metadata(path)`，读用 `zarr.open_consolidated(path)`，把 N 次元数据读合并为 1 次。
10. 大规模计算交给 Dask：`da.from_zarr(path)` 惰性读、`da.to_zarr(arr, path)` 并行写；标注维度/坐标用 Xarray `xr.open_zarr` / `ds.to_zarr`。

## 示例

基础建数组与读写：
```python
import zarr, numpy as np
z = zarr.create_array(store="data/my.zarr", shape=(10000, 10000),
                      chunks=(1000, 1000), dtype="f4")
z[:, :] = np.random.random((10000, 10000))
data = z[0:100, 0:100]            # 返回 NumPy 数组
```

分块对齐 access pattern（实测差异巨大）：
```python
# (200,200,200) 沿第一维读：chunks(1,200,200)≈107ms vs chunks(200,200,1)≈1.65ms（65×）
z_row = zarr.zeros((10000, 10000), chunks=(10, 10000))   # 常按行读
z_col = zarr.zeros((10000, 10000), chunks=(10000, 10))   # 常按列读
```

分片 + 压缩：
```python
from zarr.codecs import BloscCodec
z = zarr.create_array(store="data.zarr", shape=(100000, 100000),
                      chunks=(100, 100), shards=(1000, 1000), dtype="f4",
                      codecs=[BloscCodec(cname="zstd", clevel=5, shuffle="shuffle")])
```

云原生工作流（S3）：
```python
import zarr
# 凭证走标准 AWS 环境变量 AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_DEFAULT_REGION
z = zarr.create_array(store="s3://my-bucket/array.zarr", shape=(10000, 10000),
                      chunks=(500, 500), dtype="f4", storage_options={"anon": False})
z[:] = data
zarr.consolidate_metadata("s3://my-bucket/array.zarr")
z_read = zarr.open_consolidated("s3://my-bucket/array.zarr", storage_options={"anon": False})
```

Dask 并行 + Xarray：
```python
import dask.array as da, xarray as xr
result = da.from_zarr("data.zarr").mean(axis=0).compute()   # 越内存并行
ds = xr.open_zarr("data.zarr"); ds.sel(time="2024-01").to_zarr("out.zarr")
```

时间序列追加 / 体检：
```python
z = zarr.open("ts.zarr", mode="a", shape=(0, 720, 1440),
              chunks=(1, 720, 1440), dtype="f4")
z.append(np.random.random((1, 720, 1440)), axis=0)
print(z.info)                                # 形状/编解码/压缩比
print(z.nbytes / z.nbytes_stored)            # 压缩比
```

## 注意事项

- 块大小 1-10MB 为宜；云端对象偏大（5-100MB）更好。整块/整片须能入内存。
- 块形状对齐访问模式是头号性能因素，错配可慢几十倍。
- 压缩选型：交互/快 → `BloscCodec(cname="lz4")`；均衡 → `BloscCodec(cname="zstd", clevel=5)`；极致压缩 → `GzipCodec(level=9)`；数值数据开 `shuffle`。
- 属性 `z.attrs[...]` 必须 JSON 可序列化（str/num/list/dict/bool/null）。
- 并发写：读永远线程/进程安全；写仅在各 worker 写**不重叠**块时安全；重叠写需外部协调（文件锁/工作流设计），Zarr 3 暂无 `ThreadSynchronizer`/`ProcessSynchronizer`。
- `consolidate_metadata` 提速但会陈旧：频繁更新或多写场景慎用，更新后需重新 consolidate。
- 避免 `z[:]` 整载入内存：分块循环或交给 Dask。
- 云端凭证由 fsspec 从本地 provider 环境变量读取，不会发往配置桶/项目以外的第三方端点。
- 版本/迁移细节回查上游：https://zarr.readthedocs.io/en/stable/user-guide/v3_migration/ 。

## 互见

- related：`polars-dataframe`（表格数据另一条路线）、`scikit-learn-ml`（数组喂给 ML）、`matplotlib-visualization`（结果可视化）。
- combines_with：Dask（`da.from_zarr` 并行越内存计算）、Xarray（标注维度/坐标、NetCDF 互转）、NumCodecs（自定义编解码）。
- 格式转换：HDF5 → Zarr（`zarr.array(h5ds[:], ...)`）、NumPy `.npy` → Zarr、Zarr → NetCDF（经 Xarray `ds.to_netcdf`）。
- 上游文档：https://zarr.readthedocs.io/en/stable/ 、规范 https://zarr-specs.readthedocs.io/ 、GitHub zarr-developers/zarr-python。

---
采编自 K-Dense-AI/scientific-agent-skills（MIT），社区指南维护者 K-Dense Inc.，基于 zarr-developers/zarr-python 3.x。

