Skip to content
forked from pydata/xarray

Commit 43adc03

Browse files
committed
Merge remote-tracking branch 'upstream/main' into docstring
* upstream/main: Add typing_extensions as a required dependency (pydata#5911) pydata#5740 follow up: supress xr.ufunc warnings in tests (pydata#5914) Avoid accessing slow .data in unstack (pydata#5906) Add wradlib to ecosystem in docs (pydata#5915) Use .to_numpy() for quantified facetgrids (pydata#5886) [test-upstream] fix pd skipna=None (pydata#5899) Add var and std to weighted computations (pydata#5870)
2 parents 7b3fb24 + bcb96ce commit 43adc03

23 files changed

+404
-123
lines changed

ci/requirements/environment-windows.yml

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ dependencies:
3939
- setuptools
4040
- sparse
4141
- toolz
42+
- typing_extensions
4243
- zarr
4344
- pip:
4445
- numbagg

ci/requirements/environment.yml

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ dependencies:
4343
- setuptools
4444
- sparse
4545
- toolz
46+
- typing_extensions
4647
- zarr
4748
- pip:
4849
- numbagg

ci/requirements/py37-bare-minimum.yml

+1
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ dependencies:
1313
- numpy=1.17
1414
- pandas=1.0
1515
- setuptools=40.4
16+
- typing_extensions=3.7

ci/requirements/py37-min-all-deps.yml

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ dependencies:
4747
- setuptools=40.4
4848
- sparse=0.8
4949
- toolz=0.10
50+
- typing_extensions=3.7
5051
- zarr=2.4
5152
- pip:
5253
- numbagg==0.1

ci/requirements/py38-all-but-dask.yml

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ dependencies:
3939
- setuptools
4040
- sparse
4141
- toolz
42+
- typing_extensions
4243
- zarr
4344
- pip:
4445
- numbagg

doc/api.rst

+6
Original file line numberDiff line numberDiff line change
@@ -779,12 +779,18 @@ Weighted objects
779779

780780
core.weighted.DataArrayWeighted
781781
core.weighted.DataArrayWeighted.mean
782+
core.weighted.DataArrayWeighted.std
782783
core.weighted.DataArrayWeighted.sum
784+
core.weighted.DataArrayWeighted.sum_of_squares
783785
core.weighted.DataArrayWeighted.sum_of_weights
786+
core.weighted.DataArrayWeighted.var
784787
core.weighted.DatasetWeighted
785788
core.weighted.DatasetWeighted.mean
789+
core.weighted.DatasetWeighted.std
786790
core.weighted.DatasetWeighted.sum
791+
core.weighted.DatasetWeighted.sum_of_squares
787792
core.weighted.DatasetWeighted.sum_of_weights
793+
core.weighted.DatasetWeighted.var
788794

789795

790796
Coarsen objects

doc/ecosystem.rst

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ Geosciences
3737
- `Spyfit <https://spyfit.readthedocs.io/en/master/>`_: FTIR spectroscopy of the atmosphere
3838
- `windspharm <https://ajdawson.github.io/windspharm/index.html>`_: Spherical
3939
harmonic wind analysis in Python.
40+
- `wradlib <https://wradlib.org/>`_: An Open Source Library for Weather Radar Data Processing.
4041
- `wrf-python <https://wrf-python.readthedocs.io/>`_: A collection of diagnostic and interpolation routines for use with output of the Weather Research and Forecasting (WRF-ARW) Model.
4142
- `xarray-simlab <https://xarray-simlab.readthedocs.io>`_: xarray extension for computer model simulations.
4243
- `xarray-spatial <https://makepath.github.io/xarray-spatial>`_: Numba-accelerated raster-based spatial processing tools (NDVI, curvature, zonal-statistics, proximity, hillshading, viewshed, etc.)

doc/getting-started-guide/installing.rst

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Required dependencies
88

99
- Python (3.7 or later)
1010
- setuptools (40.4 or later)
11+
- ``typing_extensions`` (3.7 or later)
1112
- `numpy <http://www.numpy.org/>`__ (1.17 or later)
1213
- `pandas <http://pandas.pydata.org/>`__ (1.0 or later)
1314

doc/user-guide/computation.rst

+17-3
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ Weighted array reductions
263263

264264
:py:class:`DataArray` and :py:class:`Dataset` objects include :py:meth:`DataArray.weighted`
265265
and :py:meth:`Dataset.weighted` array reduction methods. They currently
266-
support weighted ``sum`` and weighted ``mean``.
266+
support weighted ``sum``, ``mean``, ``std`` and ``var``.
267267

268268
.. ipython:: python
269269
@@ -298,13 +298,27 @@ The weighted sum corresponds to:
298298
weighted_sum = (prec * weights).sum()
299299
weighted_sum
300300
301-
and the weighted mean to:
301+
the weighted mean to:
302302

303303
.. ipython:: python
304304
305305
weighted_mean = weighted_sum / weights.sum()
306306
weighted_mean
307307
308+
the weighted variance to:
309+
310+
.. ipython:: python
311+
312+
weighted_var = weighted_prec.sum_of_squares() / weights.sum()
313+
weighted_var
314+
315+
and the weighted standard deviation to:
316+
317+
.. ipython:: python
318+
319+
weighted_std = np.sqrt(weighted_var)
320+
weighted_std
321+
308322
However, the functions also take missing values in the data into account:
309323

310324
.. ipython:: python
@@ -327,7 +341,7 @@ If the weights add up to to 0, ``sum`` returns 0:
327341
328342
data.weighted(weights).sum()
329343
330-
and ``mean`` returns ``NaN``:
344+
and ``mean``, ``std`` and ``var`` return ``NaN``:
331345

332346
.. ipython:: python
333347

doc/whats-new.rst

+6
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ v0.19.1 (unreleased)
2323
2424
New Features
2525
~~~~~~~~~~~~
26+
- Add :py:meth:`var`, :py:meth:`std` and :py:meth:`sum_of_squares` to :py:meth:`Dataset.weighted` and :py:meth:`DataArray.weighted`.
27+
By `Christian Jauvin <https://github.com/cjauvin>`_.
2628
- Added a :py:func:`get_options` method to xarray's root namespace (:issue:`5698`, :pull:`5716`)
2729
By `Pushkar Kopparla <https://github.com/pkopparla>`_.
2830
- Xarray now does a better job rendering variable names that are long LaTeX sequences when plotting (:issue:`5681`, :pull:`5682`).
@@ -80,11 +82,15 @@ Bug fixes
8082
By `Jimmy Westling <https://github.com/illviljan>`_.
8183
- Numbers are properly formatted in a plot's title (:issue:`5788`, :pull:`5789`).
8284
By `Maxime Liquet <https://github.com/maximlt>`_.
85+
- Faceted plots will no longer raise a `pint.UnitStrippedWarning` when a `pint.Quantity` array is plotted,
86+
and will correctly display the units of the data in the colorbar (if there is one) (:pull:`5886`).
87+
By `Tom Nicholas <https://github.com/TomNicholas>`_.
8388
- With backends, check for path-like objects rather than ``pathlib.Path``
8489
type, use ``os.fspath`` (:pull:`5879`).
8590
By `Mike Taves <https://github.com/mwtoews>`_.
8691
- ``open_mfdataset()`` now accepts a single ``pathlib.Path`` object (:issue: `5881`).
8792
By `Panos Mavrogiorgos <https://github.com/pmav99>`_.
93+
- Improved performance of :py:meth:`Dataset.unstack` (:pull:`5906`). By `Tom Augspurger <https://github.com/TomAugspurger>`_.
8894

8995
Documentation
9096
~~~~~~~~~~~~~

requirements.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55
numpy >= 1.17
66
pandas >= 1.0
77
setuptools >= 40.4
8-
typing-extensions >= 3.10
8+
typing-extensions >= 3.7

setup.cfg

+1
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ python_requires = >=3.7
7878
install_requires =
7979
numpy >= 1.17
8080
pandas >= 1.0
81+
typing_extensions >= 3.7
8182
setuptools >= 40.4 # For pkg_resources
8283

8384
[options.extras_require]

xarray/core/dataset.py

+27-27
Original file line numberDiff line numberDiff line change
@@ -4153,34 +4153,34 @@ def unstack(
41534153
)
41544154

41554155
result = self.copy(deep=False)
4156-
for dim in dims:
41574156

4158-
if (
4159-
# Dask arrays don't support assignment by index, which the fast unstack
4160-
# function requires.
4161-
# https://github.com/pydata/xarray/pull/4746#issuecomment-753282125
4162-
any(is_duck_dask_array(v.data) for v in self.variables.values())
4163-
# Sparse doesn't currently support (though we could special-case
4164-
# it)
4165-
# https://github.com/pydata/sparse/issues/422
4166-
or any(
4167-
isinstance(v.data, sparse_array_type)
4168-
for v in self.variables.values()
4169-
)
4170-
or sparse
4171-
# Until https://github.com/pydata/xarray/pull/4751 is resolved,
4172-
# we check explicitly whether it's a numpy array. Once that is
4173-
# resolved, explicitly exclude pint arrays.
4174-
# # pint doesn't implement `np.full_like` in a way that's
4175-
# # currently compatible.
4176-
# # https://github.com/pydata/xarray/pull/4746#issuecomment-753425173
4177-
# # or any(
4178-
# # isinstance(v.data, pint_array_type) for v in self.variables.values()
4179-
# # )
4180-
or any(
4181-
not isinstance(v.data, np.ndarray) for v in self.variables.values()
4182-
)
4183-
):
4157+
# we want to avoid allocating an object-dtype ndarray for a MultiIndex,
4158+
# so we can't just access self.variables[v].data for every variable.
4159+
# We only check the non-index variables.
4160+
# https://github.com/pydata/xarray/issues/5902
4161+
nonindexes = [
4162+
self.variables[k] for k in set(self.variables) - set(self.xindexes)
4163+
]
4164+
# Notes for each of these cases:
4165+
# 1. Dask arrays don't support assignment by index, which the fast unstack
4166+
# function requires.
4167+
# https://github.com/pydata/xarray/pull/4746#issuecomment-753282125
4168+
# 2. Sparse doesn't currently support (though we could special-case it)
4169+
# https://github.com/pydata/sparse/issues/422
4170+
# 3. pint requires checking if it's a NumPy array until
4171+
# https://github.com/pydata/xarray/pull/4751 is resolved,
4172+
# Once that is resolved, explicitly exclude pint arrays.
4173+
# pint doesn't implement `np.full_like` in a way that's
4174+
# currently compatible.
4175+
needs_full_reindex = sparse or any(
4176+
is_duck_dask_array(v.data)
4177+
or isinstance(v.data, sparse_array_type)
4178+
or not isinstance(v.data, np.ndarray)
4179+
for v in nonindexes
4180+
)
4181+
4182+
for dim in dims:
4183+
if needs_full_reindex:
41844184
result = result._unstack_full_reindex(dim, fill_value, sparse)
41854185
else:
41864186
result = result._unstack_once(dim, fill_value)

xarray/core/npcompat.py

+2-9
Original file line numberDiff line numberDiff line change
@@ -41,17 +41,10 @@
4141
# fall back for numpy < 1.20, ArrayLike adapted from numpy.typing._array_like
4242
if sys.version_info >= (3, 8):
4343
from typing import Protocol
44-
45-
HAVE_PROTOCOL = True
4644
else:
47-
try:
48-
from typing_extensions import Protocol
49-
except ImportError:
50-
HAVE_PROTOCOL = False
51-
else:
52-
HAVE_PROTOCOL = True
45+
from typing_extensions import Protocol
5346

54-
if TYPE_CHECKING or HAVE_PROTOCOL:
47+
if TYPE_CHECKING:
5548

5649
class _SupportsArray(Protocol):
5750
def __array__(self) -> np.ndarray:

xarray/core/options.py

+24-59
Original file line numberDiff line numberDiff line change
@@ -6,70 +6,35 @@
66
# TODO: Remove this check once python 3.7 is not supported:
77
if sys.version_info >= (3, 8):
88
from typing import TYPE_CHECKING, Literal, TypedDict, Union
9+
else:
10+
from typing import TYPE_CHECKING, Union
911

10-
if TYPE_CHECKING:
11-
try:
12-
from matplotlib.colors import Colormap
13-
except ImportError:
14-
Colormap = str
15-
16-
class T_Options(TypedDict):
17-
arithmetic_join: Literal["inner", "outer", "left", "right", "exact"]
18-
cmap_divergent: Union[str, "Colormap"]
19-
cmap_sequential: Union[str, "Colormap"]
20-
display_max_rows: int
21-
display_style: Literal["text", "html"]
22-
display_width: int
23-
display_expand_attrs: Literal["default", True, False]
24-
display_expand_coords: Literal["default", True, False]
25-
display_expand_data_vars: Literal["default", True, False]
26-
display_expand_data: Literal["default", True, False]
27-
enable_cftimeindex: bool
28-
file_cache_maxsize: int
29-
keep_attrs: Literal["default", True, False]
30-
warn_for_unclosed_files: bool
31-
use_bottleneck: bool
12+
from typing_extensions import Literal, TypedDict
3213

3314

34-
else:
35-
# See GH5624, this is a convoluted way to allow type-checking to use
36-
# `TypedDict` and `Literal` without requiring typing_extensions as a
37-
# required dependency to _run_ the code (it is required to type-check).
15+
if TYPE_CHECKING:
3816
try:
39-
from typing import TYPE_CHECKING, Union
40-
41-
from typing_extensions import Literal, TypedDict
42-
43-
if TYPE_CHECKING:
44-
try:
45-
from matplotlib.colors import Colormap
46-
except ImportError:
47-
Colormap = str
48-
49-
class T_Options(TypedDict):
50-
arithmetic_join: Literal["inner", "outer", "left", "right", "exact"]
51-
cmap_divergent: Union[str, "Colormap"]
52-
cmap_sequential: Union[str, "Colormap"]
53-
display_max_rows: int
54-
display_style: Literal["text", "html"]
55-
display_width: int
56-
display_expand_attrs: Literal["default", True, False]
57-
display_expand_coords: Literal["default", True, False]
58-
display_expand_data_vars: Literal["default", True, False]
59-
display_expand_data: Literal["default", True, False]
60-
enable_cftimeindex: bool
61-
file_cache_maxsize: int
62-
keep_attrs: Literal["default", True, False]
63-
warn_for_unclosed_files: bool
64-
use_bottleneck: bool
65-
17+
from matplotlib.colors import Colormap
6618
except ImportError:
67-
from typing import TYPE_CHECKING, Any, Dict, Hashable
68-
69-
if TYPE_CHECKING:
70-
raise
71-
else:
72-
T_Options = Dict[Hashable, Any]
19+
Colormap = str
20+
21+
22+
class T_Options(TypedDict):
23+
arithmetic_join: Literal["inner", "outer", "left", "right", "exact"]
24+
cmap_divergent: Union[str, "Colormap"]
25+
cmap_sequential: Union[str, "Colormap"]
26+
display_max_rows: int
27+
display_style: Literal["text", "html"]
28+
display_width: int
29+
display_expand_attrs: Literal["default", True, False]
30+
display_expand_coords: Literal["default", True, False]
31+
display_expand_data_vars: Literal["default", True, False]
32+
display_expand_data: Literal["default", True, False]
33+
enable_cftimeindex: bool
34+
file_cache_maxsize: int
35+
keep_attrs: Literal["default", True, False]
36+
warn_for_unclosed_files: bool
37+
use_bottleneck: bool
7338

7439

7540
OPTIONS: T_Options = {

0 commit comments

Comments
 (0)