{"id":18295857,"url":"https://github.com/astropenguin/xarray-units","last_synced_at":"2025-04-05T12:31:45.079Z","repository":{"id":211528135,"uuid":"729396575","full_name":"astropenguin/xarray-units","owner":"astropenguin","description":":zap: xarray extension for handling units","archived":false,"fork":false,"pushed_at":"2024-02-04T07:48:21.000Z","size":1902,"stargazers_count":3,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-05-30T01:18:13.032Z","etag":null,"topics":["units","xarray","xarray-accessor","xarray-extension"],"latest_commit_sha":null,"homepage":"https://astropenguin.github.io/xarray-units/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/astropenguin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-12-09T05:13:40.000Z","updated_at":"2024-05-19T09:54:15.000Z","dependencies_parsed_at":"2024-11-05T14:45:11.815Z","dependency_job_id":null,"html_url":"https://github.com/astropenguin/xarray-units","commit_stats":null,"previous_names":["astropenguin/xarray-units"],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/astropenguin%2Fxarray-units","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/astropenguin%2Fxarray-units/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/astropenguin%2Fxarray-units/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/astropenguin%2Fxarray-units/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/astropenguin","download_url":"https://codeload.github.com/astropenguin/xarray-units/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247338954,"owners_count":20923001,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["units","xarray","xarray-accessor","xarray-extension"],"created_at":"2024-11-05T14:38:33.482Z","updated_at":"2025-04-05T12:31:40.070Z","avatar_url":"https://github.com/astropenguin.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# xarray-units\n\n[![Release](https://img.shields.io/pypi/v/xarray-units?label=Release\u0026color=cornflowerblue\u0026style=flat-square)](https://pypi.org/project/xarray-units/)\n[![Python](https://img.shields.io/pypi/pyversions/xarray-units?label=Python\u0026color=cornflowerblue\u0026style=flat-square)](https://pypi.org/project/xarray-units/)\n[![Downloads](https://img.shields.io/pypi/dm/xarray-units?label=Downloads\u0026color=cornflowerblue\u0026style=flat-square)](https://pepy.tech/project/xarray-units)\n[![DOI](https://img.shields.io/badge/DOI-10.5281/zenodo.10354517-cornflowerblue?style=flat-square)](https://doi.org/10.5281/zenodo.10354517)\n[![Tests](https://img.shields.io/github/actions/workflow/status/astropenguin/xarray-units/tests.yaml?label=Tests\u0026style=flat-square)](https://github.com/astropenguin/xarray-units/actions)\n\nxarray extension for handling units\n\n## Overview\n\nxarray-units is an import-only package that provides an [xarray](https://xarray.dev) DataArray accessor `.units` for handling units such as converting units and numeric operations considering units.\n[Astropy](https://www.astropy.org) is used as a backend.\nUnlike similar implementations, xarray-units does not use a special data type to handle units, but uses the original data type in a DataArray.\nThis allows to continue to use powerful features such as parallel and lazy processing with [Dask](https://www.dask.org) and/or user-defined DataArray subclasses.\n\n## Installation\n\n```shell\npip install xarray-units==0.5.0\n```\n\n## Basic usages\n\nSuppose the following imports will be commonly used in the examples below:\n\n```python\nimport xarray as xr\nimport xarray_units\n```\n\n### Setting and unsetting units\n\nxarray-units sets units in DataArray attributes (`.attrs`) with the name `\"units\"`:\n\n```python\nda_km = xr.DataArray([1, 2, 3]).units.set(\"km\")\nprint(da_km)\n```\n\n```\n\u003cxarray.DataArray (dim_0: 3)\u003e\narray([1, 2, 3])\nDimensions without coordinates: dim_0\nAttributes:\n    units:    km\n```\n\nAnd the units can also be unset (deleted):\n\n```python\nda = da_km.units.unset()\nprint(da)\n```\n\n```\n\u003cxarray.DataArray (dim_0: 3)\u003e\narray([1, 2, 3])\nDimensions without coordinates: dim_0\n```\n\n\u003e [!NOTE]\n\u003e These are equivalent to manually un/setting the units in the DataArray attributes, but the `units` accessor also check that the units are valid when setting.\n\n### Converting units to others\n\nxarray-units converts a DataArray with units to other units:\n\n```python\nda_km = xr.DataArray([1, 2, 3]).units.set(\"km\")\nda_m = da_km.units.to(\"m\")\nprint(da_m)\n```\n\n```\n\u003cxarray.DataArray (dim_0: 3)\u003e\narray([1000., 2000., 3000.])\nDimensions without coordinates: dim_0\nAttributes:\n    units:    m\n```\n\nAstropy [equivalencies](https://docs.astropy.org/en/stable/units/equivalencies.html) can also be used for equivalences between different types of units:\n\n```python\nfrom astropy.units import spectral\n\nda_mm = xr.DataArray([1, 2, 3]).units.set(\"mm\")\nda_GHz = da_mm.units.to(\"GHz\", spectral())\nprint(da_GHz)\n```\n\n```\n\u003cxarray.DataArray (dim_1: 3)\u003e\narray([299.792458  , 149.896229  ,  99.93081933])\nDimensions without coordinates: dim_0\nAttributes:\n    units:    GHz\n```\n\n\u003e [!TIP]\n\u003e There exist other accessor methods (e.g. `decompose`, `like`) for converting units.\n\u003e See [the package guide](https://astropenguin.github.io/xarray-units/_apidoc/xarray_units.accessor.html) for more details.\n\n### Numeric operations considering units\n\nxarray-units performs numerical operations considering units when the `units` accessor is attached to the DataArray on the left side of the operator:\n\n```python\nda_m = xr.DataArray([1000, 2000, 3000]).units.set(\"m\")\nda_km = xr.DataArray([1, 2, 3]).units.set(\"km\")\n\nda_sum_m = da_m.units + da_km\nda_sum_km = da_km.units + da_m\n\nprint(da_sum_m)\nprint(da_sum_km)\n```\n\n```\n\u003cxarray.DataArray (dim_0: 3)\u003e\narray([2000., 4000., 6000.])\nDimensions without coordinates: dim_0\nAttributes:\n    units:    m\n\n\u003cxarray.DataArray (dim_0: 3)\u003e\narray([2., 4., 6.])\nDimensions without coordinates: dim_0\nAttributes:\n    units:    km\n```\n\nThe units of the DataArray after the operation follows those of the DataArray with the `units` accessor.\nThe resulting data values will be therefore different depending on the order of the operation.\nThey are, of course, equal when considering units:\n\n```python\nda_eq = (da_sum_m.units == da_sum_km)\nprint(da_eq)\n```\n\n```\n\u003cxarray.DataArray (dim_0: 3)\u003e\narray([ True,  True,  True])\nDimensions without coordinates: dim_0\n```\n\n\u003e [!IMPORTANT]\n\u003e Because this feature is accessor-based, units are only considered for the operation right after the `units` accessor.\n\u003e See [method and operation chains](#method-and-operation-chains) for performing multiple operations at once.\n\n\u003e [!TIP]\n\u003e There exist accessor methods corresponding to each operator (e.g. `add` → `+`, `eq` → `==`).\n\u003e See [the package guide](https://astropenguin.github.io/xarray-units/_apidoc/xarray_units.accessor.html) for more details.\n\n### Formatting units\n\nxarray-units converts units to [various string formats](https://docs.astropy.org/en/stable/units/format.html):\n\n```python\nda = xr.DataArray([1, 2, 3]).units.set(\"m / s^2\")\n\nda_console = da.units.format(\"console\")\nda_latex = da.units.format(\"latex\")\n\nprint(da_console)\nprint(da_latex)\n```\n\n```\n\u003cxarray.DataArray (dim_0: 3)\u003e\narray([1, 2, 3])\nDimensions without coordinates: dim_0\nAttributes:\n    units:    m s^-2\n\n\u003cxarray.DataArray (dim_0: 3)\u003e\narray([1, 2, 3])\nDimensions without coordinates: dim_0\nAttributes:\n    units:    $\\mathrm{\\frac{m}{s^{2}}}$\n```\n\nThis is useful, for example, when plotting a DataArray:\n\n```python\nda.units.format(\"latex\").plot()\n```\n\n\u003e [!NOTE]\n\u003e By default, the units of the DataArray coordinates will also be formatted.\n\n## Advanced usages\n\n### Handling units of coordinates\n\nThe `units` accessor has an option for handling units of DataArray coordinates.\nFor example, the following code will create a DataArray with `x` and `y` coordinates in units of meters:\n\n```python\nda_m = xr.DataArray([[1, 2], [3, 4]], dims=[\"x\", \"y\"]).units.set(\"deg_C\")\nda_m = da_m.assign_coords(\n    x=xr.DataArray([1000, 2000], dims=\"x\").units.set(\"m\"),\n    y=xr.DataArray([3000, 4000], dims=\"y\").units.set(\"m\"),\n)\nprint(da_m.x)\nprint(da_m.y)\n```\n\n```\n\u003cxarray.DataArray 'x' (x: 2)\u003e\narray([1000, 2000])\nCoordinates:\n  * x        (x) int64 1000 2000\nAttributes:\n    units:    m\n\n\u003cxarray.DataArray 'y' (y: 2)\u003e\narray([3000, 4000])\nCoordinates:\n  * y        (y) int64 3000 4000\nAttributes:\n    units:    m\n```\n\nTo handling the units of the DataArray coordinates, use an option `of` for specifying them:\n\n```python\nda_km = da_m.units(of=[\"x\", \"y\"]).to(\"km\")\nprint(da_km.x)\nprint(da_km.y)\n```\n\n```\n\u003cxarray.DataArray 'x' (x: 2)\u003e\narray([1., 2.])\nCoordinates:\n  * x        (x) float64 1.0 2.0\nAttributes:\n    units:    km\n\n\u003cxarray.DataArray 'y' (y: 2)\u003e\narray([3., 4.])\nCoordinates:\n  * y        (y) float64 3.0 4.0\nAttributes:\n    units:    km\n```\n\nwhere `of` accepts the name(s) of the coordinate(s) to be accessed.\n\n### Method and operation chains\n\nThe `units` accessor has an option `chain` for chaining methods or operations while considering units:\n\n```python\nda_m = xr.DataArray([1, 2, 3]).units.set(\"m\")\nda_s = xr.DataArray([1, 2, 3]).units.set(\"s\")\nda_a = da_m.units(chain=2) / da_s / da_s\nprint(da_a)\n```\n\n```\n\u003cxarray.DataArray (dim_0: 3)\u003e\narray([1.        , 0.5       , 0.33333333])\nDimensions without coordinates: dim_0\nAttributes:\n    units:    m / s2\n```\n\nwhere `chain` is the length of chained methods or operations.\nThis is equivalent to nesting the `units` accessors:\n\n```python\n(da_m.units / da_s).units / da_s\n```\n\n### Use with static type checking\n\nxarray-units provides a special type hint `xarray_units.DataArray` with which type checkers can statically handle the `units` accessor and its methods:\n\n```python\nfrom xarray_units import DataArray\n\nda: DataArray = xr.DataArray([1, 2, 3]).units.set(\"km\")\n```\n\n\u003e [!TIP]\n\u003e `xarray_units.DataArray` will be replaced by `xarray.DataArray` at runtime, so it can also be used for creating and subclassing `DataArray`.\n\n### Use without the units accessor\n\nxarray-units provides a function `xarray_units.units` that returns the `units` accessor of a DataArray.\nThe following two codes are therefore equivalent:\n\n```python\nxr.DataArray([1, 2, 3]).units.set(\"km\")\n```\n\n```python\nfrom xarray_units import units\n\nunits(xr.DataArray([1, 2, 3])).set(\"km\")\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fastropenguin%2Fxarray-units","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fastropenguin%2Fxarray-units","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fastropenguin%2Fxarray-units/lists"}