Skip to content
forked from pydata/xarray

Commit e114cad

Browse files
committed
Merge remote-tracking branch 'upstream/master' into sparse-fixes
* upstream/master: Initialize empty or full DataArray (pydata#3159) Raise on inplace=True (pydata#3260) added support for rasterio geotiff tags (pydata#3249) Remove sel_points (pydata#3261) Fix sparse ops that were calling bottleneck (pydata#3254) New feature of filter_by_attrs added (pydata#3259) Update filter_by_attrs to use 'variables' instead of 'data_vars' (pydata#3247)
2 parents 5722517 + 3c020e5 commit e114cad

12 files changed

+167
-578
lines changed

doc/indexing.rst

-8
Original file line numberDiff line numberDiff line change
@@ -392,14 +392,6 @@ These methods may also be applied to ``Dataset`` objects
392392
You may find increased performance by loading your data into memory first,
393393
e.g., with :py:meth:`~xarray.Dataset.load`.
394394

395-
.. note::
396-
397-
Vectorized indexing is a new feature in v0.10.
398-
In older versions of xarray, dimensions of indexers are ignored.
399-
Dedicated methods for some advanced indexing use cases,
400-
``isel_points`` and ``sel_points`` are now deprecated.
401-
See :ref:`more_advanced_indexing` for their alternative.
402-
403395
.. note::
404396

405397
If an indexer is a :py:meth:`~xarray.DataArray`, its coordinates should not

doc/whats-new.rst

+18
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,17 @@ v0.13.0 (unreleased)
2121
This release increases the minimum required Python version from 3.5.0 to 3.5.3
2222
(:issue:`3089`). By `Guido Imperiale <https://github.com/crusaderky>`_.
2323

24+
Breaking changes
25+
~~~~~~~~~~~~~~~~
26+
27+
- The ``isel_points`` and ``sel_points`` methods are removed, having been deprecated
28+
since v0.10.0. These are redundant with the ``isel`` / ``sel`` methods.
29+
See :ref:`vectorized_indexing` for the details
30+
By `Maximilian Roos <https://github.com/max-sixty>`_
31+
- The ``inplace`` kwarg for public methods now raises an error, having been deprecated
32+
since v0.11.0.
33+
By `Maximilian Roos <https://github.com/max-sixty>`_
34+
2435
New functions/methods
2536
~~~~~~~~~~~~~~~~~~~~~
2637

@@ -64,6 +75,11 @@ Enhancements
6475
- In :py:meth:`~xarray.Dataset.to_zarr`, passing ``mode`` is not mandatory if
6576
``append_dim`` is set, as it will automatically be set to ``'a'`` internally.
6677
By `David Brochart <https://github.com/davidbrochart>`_.
78+
79+
- Added the ability to initialize an empty or full DataArray
80+
with a single value. (:issue:`277`)
81+
By `Gerardo Rivera <http://github.com/dangomelon>`_.
82+
6783
- :py:func:`~xarray.Dataset.to_netcdf()` now supports the ``invalid_netcdf`` kwarg when used
6884
with ``engine="h5netcdf"``. It is passed to :py:func:`h5netcdf.File`.
6985
By `Ulrich Herter <https://github.com/ulijh>`_.
@@ -78,6 +94,8 @@ Enhancements
7894
:py:meth:`DataArray.set_index`, as well are more specific error messages
7995
when the user passes invalid arguments (:issue:`3176`).
8096
By `Gregory Gundersen <https://github.com/gwgundersen>`_.
97+
98+
- :py:func:`filter_by_attrs` now filters the coordinates as well as the variables. By `Spencer Jones <https://github.com/cspencerjones>`_.
8199

82100
Bug fixes
83101
~~~~~~~~~

xarray/backends/rasterio_.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -322,11 +322,14 @@ def open_rasterio(filename, parse_coordinates=None, chunks=None, cache=None, loc
322322
attrs["units"] = riods.units
323323

324324
# Parse extra metadata from tags, if supported
325-
parsers = {"ENVI": _parse_envi}
325+
parsers = {"ENVI": _parse_envi, "GTiff": lambda m: m}
326326

327327
driver = riods.driver
328328
if driver in parsers:
329-
meta = parsers[driver](riods.tags(ns=driver))
329+
if driver == "GTiff":
330+
meta = parsers[driver](riods.tags())
331+
else:
332+
meta = parsers[driver](riods.tags(ns=driver))
330333

331334
for k, v in meta.items():
332335
# Add values as coordinates if they match the band count,

xarray/core/dataarray.py

+32-74
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,24 @@ def _infer_coords_and_dims(
158158
return new_coords, dims
159159

160160

161+
def _check_data_shape(data, coords, dims):
162+
if data is dtypes.NA:
163+
data = np.nan
164+
if coords is not None and utils.is_scalar(data, include_0d=False):
165+
if utils.is_dict_like(coords):
166+
if dims is None:
167+
return data
168+
else:
169+
data_shape = tuple(
170+
as_variable(coords[k], k).size if k in coords.keys() else 1
171+
for k in dims
172+
)
173+
else:
174+
data_shape = tuple(as_variable(coord, "foo").size for coord in coords)
175+
data = np.full(data_shape, data)
176+
return data
177+
178+
161179
class _LocIndexer:
162180
def __init__(self, data_array: "DataArray"):
163181
self.data_array = data_array
@@ -234,7 +252,7 @@ class DataArray(AbstractArray, DataWithCoords):
234252

235253
def __init__(
236254
self,
237-
data: Any,
255+
data: Any = dtypes.NA,
238256
coords: Union[Sequence[Tuple], Mapping[Hashable, Any], None] = None,
239257
dims: Union[Hashable, Sequence[Hashable], None] = None,
240258
name: Hashable = None,
@@ -323,6 +341,7 @@ def __init__(
323341
if encoding is None:
324342
encoding = getattr(data, "encoding", None)
325343

344+
data = _check_data_shape(data, coords, dims)
326345
data = as_compatible_data(data)
327346
coords, dims = _infer_coords_and_dims(data.shape, coords, dims)
328347
variable = Variable(dims, data, attrs, encoding, fastpath=True)
@@ -700,30 +719,17 @@ def reset_coords(
700719
drop : bool, optional
701720
If True, remove coordinates instead of converting them into
702721
variables.
703-
inplace : bool, optional
704-
If True, modify this object in place. Otherwise, create a new
705-
object.
706722
707723
Returns
708724
-------
709-
Dataset, or DataArray if ``drop == True``, or None if
710-
``inplace == True``
725+
Dataset, or DataArray if ``drop == True``
711726
"""
712-
inplace = _check_inplace(inplace)
713-
if inplace and not drop:
714-
raise ValueError(
715-
"cannot reset coordinates in-place on a "
716-
"DataArray without ``drop == True``"
717-
)
727+
_check_inplace(inplace)
718728
if names is None:
719729
names = set(self.coords) - set(self.dims)
720730
dataset = self.coords.to_dataset().reset_coords(names, drop)
721731
if drop:
722-
if inplace:
723-
self._coords = dataset._variables
724-
return None
725-
else:
726-
return self._replace(coords=dataset._variables)
732+
return self._replace(coords=dataset._variables)
727733
else:
728734
if self.name is None:
729735
raise ValueError(
@@ -1026,32 +1032,6 @@ def sel(
10261032
)
10271033
return self._from_temp_dataset(ds)
10281034

1029-
def isel_points(self, dim="points", **indexers) -> "DataArray":
1030-
"""Return a new DataArray whose data is given by pointwise integer
1031-
indexing along the specified dimension(s).
1032-
1033-
See Also
1034-
--------
1035-
Dataset.isel_points
1036-
"""
1037-
ds = self._to_temp_dataset().isel_points(dim=dim, **indexers)
1038-
return self._from_temp_dataset(ds)
1039-
1040-
def sel_points(
1041-
self, dim="points", method=None, tolerance=None, **indexers
1042-
) -> "DataArray":
1043-
"""Return a new DataArray whose dataset is given by pointwise selection
1044-
of index labels along the specified dimension(s).
1045-
1046-
See Also
1047-
--------
1048-
Dataset.sel_points
1049-
"""
1050-
ds = self._to_temp_dataset().sel_points(
1051-
dim=dim, method=method, tolerance=tolerance, **indexers
1052-
)
1053-
return self._from_temp_dataset(ds)
1054-
10551035
def broadcast_like(
10561036
self, other: Union["DataArray", Dataset], exclude: Iterable[Hashable] = None
10571037
) -> "DataArray":
@@ -1511,9 +1491,6 @@ def set_index(
15111491
append : bool, optional
15121492
If True, append the supplied index(es) to the existing index(es).
15131493
Otherwise replace the existing index(es) (default).
1514-
inplace : bool, optional
1515-
If True, set new index(es) in-place. Otherwise, return a new
1516-
DataArray object.
15171494
**indexes_kwargs: optional
15181495
The keyword arguments form of ``indexes``.
15191496
One of indexes or indexes_kwargs must be provided.
@@ -1522,7 +1499,6 @@ def set_index(
15221499
-------
15231500
obj : DataArray
15241501
Another DataArray, with this data but replaced coordinates.
1525-
Return None if inplace=True.
15261502
15271503
Example
15281504
-------
@@ -1552,14 +1528,10 @@ def set_index(
15521528
--------
15531529
DataArray.reset_index
15541530
"""
1555-
inplace = _check_inplace(inplace)
1531+
_check_inplace(inplace)
15561532
indexes = either_dict_or_kwargs(indexes, indexes_kwargs, "set_index")
15571533
coords, _ = merge_indexes(indexes, self._coords, set(), append=append)
1558-
if inplace:
1559-
self._coords = coords
1560-
return None
1561-
else:
1562-
return self._replace(coords=coords)
1534+
return self._replace(coords=coords)
15631535

15641536
def reset_index(
15651537
self,
@@ -1577,36 +1549,29 @@ def reset_index(
15771549
drop : bool, optional
15781550
If True, remove the specified indexes and/or multi-index levels
15791551
instead of extracting them as new coordinates (default: False).
1580-
inplace : bool, optional
1581-
If True, modify the dataarray in-place. Otherwise, return a new
1582-
DataArray object.
15831552
15841553
Returns
15851554
-------
15861555
obj : DataArray
15871556
Another dataarray, with this dataarray's data but replaced
1588-
coordinates. If ``inplace == True``, return None.
1557+
coordinates.
15891558
15901559
See Also
15911560
--------
15921561
DataArray.set_index
15931562
"""
1594-
inplace = _check_inplace(inplace)
1563+
_check_inplace(inplace)
15951564
coords, _ = split_indexes(
15961565
dims_or_levels, self._coords, set(), self._level_coords, drop=drop
15971566
)
1598-
if inplace:
1599-
self._coords = coords
1600-
return None
1601-
else:
1602-
return self._replace(coords=coords)
1567+
return self._replace(coords=coords)
16031568

16041569
def reorder_levels(
16051570
self,
16061571
dim_order: Mapping[Hashable, Sequence[int]] = None,
16071572
inplace: bool = None,
16081573
**dim_order_kwargs: Sequence[int]
1609-
) -> Optional["DataArray"]:
1574+
) -> "DataArray":
16101575
"""Rearrange index levels using input order.
16111576
16121577
Parameters
@@ -1615,9 +1580,6 @@ def reorder_levels(
16151580
Mapping from names matching dimensions and values given
16161581
by lists representing new level orders. Every given dimension
16171582
must have a multi-index.
1618-
inplace : bool, optional
1619-
If True, modify the dataarray in-place. Otherwise, return a new
1620-
DataArray object.
16211583
**dim_order_kwargs: optional
16221584
The keyword arguments form of ``dim_order``.
16231585
One of dim_order or dim_order_kwargs must be provided.
@@ -1626,9 +1588,9 @@ def reorder_levels(
16261588
-------
16271589
obj : DataArray
16281590
Another dataarray, with this dataarray's data but replaced
1629-
coordinates. If ``inplace == True``, return None.
1591+
coordinates.
16301592
"""
1631-
inplace = _check_inplace(inplace)
1593+
_check_inplace(inplace)
16321594
dim_order = either_dict_or_kwargs(dim_order, dim_order_kwargs, "reorder_levels")
16331595
replace_coords = {}
16341596
for dim, order in dim_order.items():
@@ -1639,11 +1601,7 @@ def reorder_levels(
16391601
replace_coords[dim] = IndexVariable(coord.dims, index.reorder_levels(order))
16401602
coords = self._coords.copy()
16411603
coords.update(replace_coords)
1642-
if inplace:
1643-
self._coords = coords
1644-
return None
1645-
else:
1646-
return self._replace(coords=coords)
1604+
return self._replace(coords=coords)
16471605

16481606
def stack(
16491607
self,

0 commit comments

Comments
 (0)