name: zarr-chunked-arrays title: Zarr 云端分块 N 维数组 description: 当需要为超大 N 维科学数组(气候/遥感/影像)做分块、压缩与并行读写,或要把数据放到 S3/GCS 做云原生工作流,或与 NumPy/Dask/Xarray 互通时使用;做 Zarr 3 数组/组的创建、分块与分片策略选型、压缩编解码配置、云端 fsspec 存储与元数据合并,产出 .zarr 存储与读写代码;不适用于纯内存中小型数组(直接用 NumPy)或关系/表格数据(用 Parquet/数据库)。触发词:zarr、分块数组、云端 N 维数组、chunks 分片 sharding、Xarray Dask Zarr domain: 数据/wrangling triggers: [zarr, 分块 N 维数组, 云端大数组存储, chunks 分块策略, sharding 分片, Blosc Zstd 压缩, S3 GCS fsspec 存储, consolidate_metadata 元数据合并, Xarray open_zarr, Dask from_zarr 并行] tags: [数据, misc, zarr, chunked-array, cloud-storage, compression, xarray, dask, scientific-computing] level: 进阶 status: stable agents: [claude-code, codex, cursor, gemini-cli] tools: [python, zarr, uv, fsspec, dask, xarray] requires: [] related: [dask-distributed-dataframes, polars-dataframe, scientific-exploratory-data-analysis, spark-job-optimization] combines_with: [dask-distributed-dataframes, matplotlib-visualization] license: MIT source: K-Dense-AI/scientific-agent-skills source_license: MIT
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,需自行设计无重叠写入或外部锁。 - 任务与上述范围不明确匹配、缺少输入/权限/成功标准时,先停下澄清;产物不替代针对具体环境的校验与评审。
步骤 / 指令
- 安装(需 Python 3.12+):
uv pip install "zarr>=3.2,<4";云端再装uv pip install "zarr[remote]" s3fs gcsfs。仅在被迫留在 Zarr v2 时用zarr==2.*。 - 选存储后端:本地
LocalStore(字符串路径即可)、临时MemoryStore、打包ZipStore(用完必须store.close())、云端用s3:///gs://URI 或FsspecStore.from_url(...)。 - 建数组:
zarr.create_array(store=..., shape=..., chunks=..., dtype=...);或便捷函数zarr.zeros/ones/full/array/zeros_like。新数组默认 Zarr format 3,需旧版互通时传zarr_format=2。 - 定分块(性能关键):目标每块 ~1-10MB;块形状对齐访问模式 —— 常按行读则块跨列、常按列读则块跨行、随机访问用方块。整块须能装入内存(压缩时)。
- 海量小块时用分片:
shards=(...)把多个 chunk 聚成一个存储对象,减少文件/对象数(整个 shard 须能入内存)。 - 配压缩:默认 Blosc+Zstd;通过
codecs=[BloscCodec(...)/GzipCodec(...)/BytesCodec()]调整或关闭。数值数据开shuffle提升压缩比。 - 读写:NumPy 式索引
z[i:j, :];高级索引z.vindex/z.oindex/z.blocks;扩容z.resize((...)),追加z.append(arr, axis=0)。 - 组织层级:
zarr.group()建组,组内create_array/require_array(v3 已移除 h5py 风格的create_dataset);root.tree()查看结构。 - 云端/多数组提速:写完
zarr.consolidate_metadata(path),读用zarr.open_consolidated(path),把 N 次元数据读合并为 1 次。 - 大规模计算交给 Dask:
da.from_zarr(path)惰性读、da.to_zarr(arr, path)并行写;标注维度/坐标用 Xarrayxr.open_zarr/ds.to_zarr。
示例
基础建数组与读写:
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(实测差异巨大):
# (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)) # 常按列读
分片 + 压缩:
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):
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:
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")
时间序列追加 / 体检:
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(经 Xarrayds.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。