10000 Docs: User Guide for Complex Numbers (#10235) · pydata/xarray@54ef8d2 · GitHub
[go: up one dir, main page]

Skip to content

Commit 54ef8d2

Browse files
andrewendlingerkmuehlbauerpre-commit-ci[bot]
authored
Docs: User Guide for Complex Numbers (#10235)
* added complex-numbers guide to doc/user-guide * added complex-numbers guide to the user-guide index * mentioned changes in whats-new * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: Kai Mühlbauer <kai.muehlbauer@uni-bonn.de> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 07430e1 commit 54ef8d2

File tree

3 files changed

+128
-0
lines changed

3 files changed

+128
-0
lines changed

doc/user-guide/complex-numbers.rst

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
.. currentmodule:: xarray
2+
3+
.. _complex:
4+
5+
Complex Numbers
6+
===============
7+
8+
Xarray leverages NumPy to seamlessly handle complex numbers in :py:class:`~xarray.DataArray` and :py:class:`~xarray.Dataset` objects.
9+
10+
In the examples below, we are using a DataArray named ``da`` with complex elements (of :math:`\mathbb{C}`):
11+
12+
.. ipython:: python
13+
14+
import xarray as xr
15+
import numpy as np
16+
17+
data = np.array([[1 + 2j, 3 + 4j], [5 + 6j, 7 + 8j]])
18+
da = xr.DataArray(
19+
data,
20+
dims=["x", "y"],
21+
coords={"x": ["a", "b"], "y": [1, 2]},
22+
name="complex_nums",
23+
)
24+
25+
26+
Operations on Complex Data
27+
--------------------------
28+
You can access real and imaginary components using the ``.real`` and ``.imag`` attributes. Most NumPy universal functions (ufuncs) like :py:doc:`numpy.abs <numpy:reference/generated/numpy.absolute>` or :py:doc:`numpy.angle <numpy:reference/generated/numpy.angle>` work directly.
29+
30+
.. ipython:: python
31+
32+
da.real
33+
np.abs(da)
34+
35+
.. note::
36+
Like NumPy, ``.real`` and ``.imag`` typically return *views*, not copies, of the original data.
37+
38+
39+
Reading and Writing Complex Data
40+
--------------------------------
41+
42+
Writing complex data to NetCDF files (see :ref:`io.netcdf`) is supported via :py:meth:`~xarray.DataArray.to_netcdf` using specific backend engines that handle complex types:
43+
44+
45+
.. tab:: h5netcdf
46+
47+
This requires the `h5netcdf <https://h5netcdf.org>`_ library to be installed.
48+
49+
.. ipython:: python
50+
:okwarning:
51+
52+
# write the data to disk
53+
da.to_netcdf("complex_nums_h5.nc", engine="h5netcdf")
54+
# read the file back into memory
55+
ds_h5 = xr.open_dataset("complex_nums_h5.nc", engine="h5netcdf")
56+
# check the dtype
57+
ds_h5[da.name].dtype
58+
59+
60+
.. tab:: netcdf4
61+
62+
Requires the `netcdf4-python (>= 1.7.1) <https://github.com/Unidata/netcdf4-python>`_ library and you have to enable ``auto_complex=True``.
63+
64+
.. ipython:: python
65+
:okwarning:
66+
67+
# write the data to disk
68+
da.to_netcdf("complex_nums_nc4.nc", engine="netcdf4", auto_complex=True)
69+
# read the file back into memory
70+
ds_nc4 = xr.open_dataset(
71+
"complex_nums_nc4.nc", engine="netcdf4", auto_complex=True
72+
)
73+
# check the dtype
74+
ds_nc4[da.name].dtype
75+
76+
77+
.. warning::
78+
The ``scipy`` engine only supports NetCDF V3 and does *not* support complex arrays; writing with ``engine="scipy"`` raises a ``TypeError``.
79+
80+
81+
Alternative: Manual Handling
82+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
83+
84+
If direct writing is not supported (e.g., targeting NetCDF3), you can manually
85+
split the complex array into separate real and imaginary variables before saving:
86+
87+
.. ipython:: python
88+
89+
# Write data to file
90+
ds_manual = xr.Dataset(
91+
{
92+
f"{da.name}_real": da.real,
93+
f"{da.name}_imag": da.imag,
94+
}
95+
)
96+
ds_manual.to_netcdf("complex_manual.nc", engine="scipy") # Example
97+
98+
# Read data from file
99+
ds = xr.open_dataset("complex_manual.nc", engine="scipy")
100+
reconstructed = ds[f"{da.name}_real"] + 1j * ds[f"{da.name}_imag"]
101+
102+
Recommendations
103+
^^^^^^^^^^^^^^^
104+
105+
- Use ``engine="netcdf4"`` with ``auto_complex=True`` for full compliance and ease.
106+
- Use ``h5netcdf`` for HDF5-based storage when interoperability with HDF5 is desired.
107+
- For maximum legacy support (NetCDF3), manually handle real/imaginary components.
108+
109+
.. ipython:: python
110+
:suppress:
111+
112+
# Cleanup
113+
import os
114+
115+
for f in ["complex_nums_nc4.nc", "complex_nums_h5.nc", "complex_manual.nc"]:
116+
if os.path.exists(f):
117+
os.remove(f)
118+
119+
120+
121+
See also
122+
--------
123+
- :ref:`io.netcdf` — full NetCDF I/O guide
124+
- `NumPy complex numbers <https://numpy.org/doc/stable/user/basics.types.html#complex>`__

doc/user-guide/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ examples that describe many common tasks that you can accomplish with Xarray.
3232
:caption: I/O
3333

3434
io
35+
complex-numbers
3536

3637
.. toctree::
3738
:maxdepth: 2

doc/whats-new.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,9 @@ Documentation
159159
- Switch to `pydata-sphinx-theme <https://github.com/pydata/pydata-sphinx-theme>`_ from `sphinx-book-theme <https://github.com/executablebooks/sphinx-book-theme>`_ (:pull:`8708`).
160160
By `Scott Henderson <https://github.com/scottyhq>`_.
161161

162+
- Add a dedicated 'Complex Numbers' sections to the User Guide (:issue:`10213`, :pull:`10235`).
163+
By `Andre Wendlinger <https://github.com/andrewendlinger>`_.
164+
162165
Internal Changes
163166
~~~~~~~~~~~~~~~~
164167
- Avoid stacking when grouping by a chunked array. This can be a large performance improvement.

0 commit comments

Comments
 (0)
0