像訪問本地文件系統同樣訪問雲存儲

微信公衆號:測度空間html

1. 什麼是Zarr?

Zarr官方網站將Zarr描述爲一個提供了分塊(chunked),壓縮(compressed),N維數組功能的Python包。 Chunked表示Zarr能夠處理很是大的數據集和快速數據訪問。compressed意味着Zarr可使用合理的文件大小來保存文件,這也意味着更低的成本。 N維數組功能說明Zarr能夠像Netcdf同樣處理多維數據集,好比,有時間,x,y和z四維的地球科學類數據集。python

Zarr的一些亮點以下:api

  • 可使用NumPy建立N維數組。
  • 沿任何維度的塊陣列。
  • 使用任何NumCodecs編解碼器壓縮和/或過濾塊陣列。
  • 將數組存儲在內存中,磁盤上,Zip文件中,雲存儲上(例如AWS S3),...
  • 從多個線程或進程併發讀取數組。
  • 從多個線程或進程併發寫入數組。
  • 經過組將數組組織到層次結構中。

Zarr最關鍵的組件是它可讓你您的本地文件系統同樣讀取和寫入文件到雲存儲系統(例如AWS S3),並且保持了Netcdf的數據組織格式。數組

2. 讀取netcdf文件

在這裏,咱們將使用NCEP Reanalysis Dataset的地面氣溫數據做爲示例。我首先將2019年地表氣溫文件air.sig995.2019.nc下載到本地電腦上。而後,利用xarray讀取文件中的數據。bash

import xarray as xr

ds = xr.open_dataset('air.sig995.2019.nc')
ds
複製代碼
<xarray.Dataset>
    Dimensions:    (lat: 73, lon: 144, nbnds: 2, time: 116)
    Coordinates:
      * lat        (lat) float32 90.0 87.5 85.0 82.5 ... -82.5 -85.0 -87.5 -90.0
      * lon        (lon) float32 0.0 2.5 5.0 7.5 10.0 ... 350.0 352.5 355.0 357.5
      * time       (time) datetime64[ns] 2019-01-01 2019-01-02 ... 2019-04-26
    Dimensions without coordinates: nbnds
    Data variables:
        air        (time, lat, lon) float32 ...
        time_bnds  (time, nbnds) float64 ...
    Attributes:
        Conventions:    COARDS
        title:          mean daily NMC reanalysis (2014)
        history:        created 2017/12 by Hoop (netCDF2.3)
        description:    Data is from NMC initialized reanalysis\n(4x/day).  These...
        platform:       Model
        References:     http://www.esrl.noaa.gov/psd/data/gridded/data.ncep.reana...
        dataset_title:  NCEP-NCAR Reanalysis 1

複製代碼
ds.air
複製代碼
<xarray.DataArray 'air' (time: 116, lat: 73, lon: 144)>
    [1219392 values with dtype=float32]
    Coordinates:
      * lat      (lat) float32 90.0 87.5 85.0 82.5 80.0 ... -82.5 -85.0 -87.5 -90.0
      * lon      (lon) float32 0.0 2.5 5.0 7.5 10.0 ... 350.0 352.5 355.0 357.5
      * time     (time) datetime64[ns] 2019-01-01 2019-01-02 ... 2019-04-26
    Attributes:
        long_name:     mean Daily Air temperature at sigma level 995
        units:         degK
        precision:     2
        GRIB_id:       11
        GRIB_name:     TMP
        var_desc:      Air temperature
        dataset:       NCEP Reanalysis Daily Averages
        level_desc:    Surface
        statistic:     Mean
        parent_stat:   Individual Obs
        valid_range:   [185.16 331.16]
        actual_range:  [198.4 314. ]
複製代碼

從上面的結果,咱們能夠看到air變量是平均日氣溫,單位爲degK。 這個變量有三個維度-時間,經度(lon)和緯度(lat)。微信

3. 將數據保存爲Zarr格式

如今咱們將把上面的數據保存爲Zarr格式。 由於我沒有AWS賬戶,因此我要將它保存到個人筆記本電腦中。 請注意,若是你有AWS帳戶的話,你能夠在s3fs包的幫助下直接將其保存到AWS S3上。 s3fs是S3的Python文件接口,它構建於boto3之上,boto3是適用於Python的Amazon Web Services(AWS)SDK。併發

import zarr
import s3fs


# Compare the data if needed
compressor = zarr.Blosc(cname='zstd', clevel=3)
encoding = {vname: {'compressor': compressor} for vname in ds.data_vars}
# Save to zarr
ds.to_zarr(store='zarr_example', encoding=encoding, consolidated=True)
複製代碼
<xarray.backends.zarr.ZarrStore at 0x31a4d1ef0>
複製代碼

如今,咱們已將數據保存爲本地zarr文件。oop

如下代碼可用於將數據保存到AWS S3 zarr格式。大數據

import zarr
import s3fs

# AWS S3 path
s3_path = 's3://your_data_path/zarr_example'
# Initilize the S3 file system
s3 = s3fs.S3FileSystem()
store = s3fs.S3Map(root=s3_path, s3=s3, check=False)
# Compare the data if needed
compressor = zarr.Blosc(cname='zstd', clelve=3)
encoding = {vname: {'compressor': compressor} for vname in ds.data_vars}
# Save to zarr
ds.to_zarr(store=store, encoding=encoding, consolidated=True)
複製代碼

4. 讀取Zarr文件

讀取Zarr文件也很容易。 你能夠直接從雲存儲系統(例如AWS S3)讀取zarr文件,這對於地球科學類的數據尤其重要。 用Zarr咱們能夠直接訪問整個或部分數據集。 想象一下,全部天氣氣候模型和衛星的數據(例如NCEP再分析數據)都保存在雲存儲上(這多是數千TB或PB),咱們能夠輕輕鬆鬆使用幾行代碼直接從AWS S3讀取和下載文件,而無需常常經理那些痛苦、耗時的數據下載過程。這會讓咱們的生活變得多麼美好!網站

由於我沒有AWS S3帳戶,我將使用本地zarr文件做爲示例。

# Read Zarr file
zarr_ds = xr.open_zarr(store='zarr_example', consolidated=True)
zarr_ds
複製代碼
<xarray.Dataset>
Dimensions:    (lat: 73, lon: 144, nbnds: 2, time: 116)
Coordinates:
  * lat        (lat) float32 90.0 87.5 85.0 82.5 ... -82.5 -85.0 -87.5 -90.0
  * lon        (lon) float32 0.0 2.5 5.0 7.5 10.0 ... 350.0 352.5 355.0 357.5
  * time       (time) datetime64[ns] 2019-01-01 2019-01-02 ... 2019-04-26
Dimensions without coordinates: nbnds
Data variables:
    air        (time, lat, lon) float32 dask.array<shape=(116, 73, 144), chunksize=(58, 37, 72)>
    time_bnds  (time, nbnds) float64 dask.array<shape=(116, 2), chunksize=(116, 2)>
Attributes:
    Conventions:    COARDS
    References:     http://www.esrl.noaa.gov/psd/data/gridded/data.ncep.reana...
    dataset_title:  NCEP-NCAR Reanalysis 1
    description:    Data is from NMC initialized reanalysis\n(4x/day).  These...
    history:        created 2017/12 by Hoop (netCDF2.3)
    platform:       Model
    title:          mean daily NMC reanalysis (2014)
複製代碼

很簡單吧? 實際上,此處zarr只讀取了數據文件的元數據而不是加載了全部真實的數據。當數據量很大時,這個功能很是有用。由於一般狀況下,咱們並不會用到全部的數據,用到的只是數據集中的一部分。例如,咱們能夠只讀取2019年1月的氣溫數據。

import pandas as pd

# We'd like the read data in Januray 2019
time_period = pd.date_range('2019-01-01', '2019-01-31')
# Select part of the zarr data
zarr_Jan = zarr_ds.sel(time=time_period)
zarr_Jan
複製代碼
<xarray.Dataset>
Dimensions:    (lat: 73, lon: 144, nbnds: 2, time: 31)
Coordinates:
  * lat        (lat) float32 90.0 87.5 85.0 82.5 ... -82.5 -85.0 -87.5 -90.0
  * lon        (lon) float32 0.0 2.5 5.0 7.5 10.0 ... 350.0 352.5 355.0 357.5
  * time       (time) datetime64[ns] 2019-01-01 2019-01-02 ... 2019-01-31
Dimensions without coordinates: nbnds
Data variables:
    air        (time, lat, lon) float32 dask.array<shape=(31, 73, 144), chunksize=(31, 37, 72)>
    time_bnds  (time, nbnds) float64 dask.array<shape=(31, 2), chunksize=(31, 2)>
Attributes:
    Conventions:    COARDS
    References:     http://www.esrl.noaa.gov/psd/data/gridded/data.ncep.reana...
    dataset_title:  NCEP-NCAR Reanalysis 1
    description:    Data is from NMC initialized reanalysis\n(4x/day).  These...
    history:        created 2017/12 by Hoop (netCDF2.3)
    platform:       Model
    title:          mean daily NMC reanalysis (2014)
複製代碼

以上咱們僅選取了2019年一月的數據。簡單吧?

如下代碼可用於訪問AWS S3 zarr文件。

# AWS S3 path
s3_path = 's3://your_data_path/zarr_example'
# Initilize the S3 file system
s3 = s3fs.S3FileSystem()
sotre = s3fs.S3Map(root=s3_path, s3=s3, check=False)
# Read Zarr file
ds = xr.open_zarr(store=store, consolidated=True)
複製代碼

5. 快速訪問的祕訣:"consolidated = True"

一旦zarr數據是固定下來而且能夠被視爲只讀,咱們就能夠經過參數consolidated = True將許多元數據對象合併爲單個對象。這樣作就能夠大大提升讀取數據集元數據的速度,讓讀取數據變得很是快捷!

6. 總結

利用Zarr,咱們能夠輕鬆地將文件讀取和寫入雲存儲系統(例如AWS S3),這對使用雲存儲系統存儲和訪問大數據很是有用。 Zarr的compressedconsolidated功能還能夠幫助咱們節省存儲成本並提升數據訪問速度。雲端N維數據的讀寫是一個很是熱門的話題。 除了Zarr以外,如今還有其餘一些包。 不過到目前爲止,Zarr是這方面的領先者。

相關文章
相關標籤/搜索