Skip to content

Commit

Permalink
BUG fix +test .sel method gives error with float32 values (#3153)
Browse files Browse the repository at this point in the history
* BUG fix +test .sel method gives error with float32 values

    .sel method gives error when it is used to select float32 values

    Resolves: #3137

* BUG  .sel method gives error with float32 values

avoid copying indexers for efficiency

* BUG: .sel method fails when label is float differnt from coords float type

casting at a lower level closer to pandas.Index methods

* BUG: .sel method fails when label is float differnt from coords float type

casting at a lower level closer to pandas.Index methods

* Update xarray/core/indexing.py

Co-Authored-By: Stephan Hoyer <[email protected]>

* BUG: .sel method gives error when label is float different from coords float type

generalizing to coerce  numpy arrays in addtion to lists/floats

* Black
  • Loading branch information
HasanAhmadQ7 authored and shoyer committed Aug 10, 2019
1 parent 362ae55 commit 097306b
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 1 deletion.
3 changes: 3 additions & 0 deletions doc/whats-new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ Bug fixes
- XFAIL several tests which are expected to fail on ARM systems
due to a ``datetime`` issue in NumPy (:issue:`2334`).
By `Graham Inggs <https://github.com/ginggs>`_.
- Fix KeyError that arises when using .sel method with float values
different from coords float type (:issue:`3137`).
By `Hasan Ahmad <https://github.com/HasanAhmadQ7>`_.
- Fixed bug in ``combine_by_coords()`` causing a `ValueError` if the input had
an unused dimension with coordinates which were not monotonic (:issue:`3150`).
By `Tom Nicholas <http://github.com/TomNicholas>`_.
Expand Down
4 changes: 3 additions & 1 deletion xarray/core/indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from . import duck_array_ops, nputils, utils
from .npcompat import DTypeLike
from .pycompat import dask_array_type, integer_types
from .utils import is_dict_like
from .utils import is_dict_like, maybe_cast_to_coords_dtype


def expanded_indexer(key, ndim):
Expand Down Expand Up @@ -269,6 +269,8 @@ def remap_label_indexers(data_obj, indexers, method=None, tolerance=None):
)
pos_indexers[dim] = label
else:
coords_dtype = data_obj.coords[dim].dtype
label = maybe_cast_to_coords_dtype(label, coords_dtype)
idxr, new_idx = convert_label_indexer(index, label, dim, method, tolerance)
pos_indexers[dim] = idxr
if new_idx is not None:
Expand Down
6 changes: 6 additions & 0 deletions xarray/core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ def _maybe_cast_to_cftimeindex(index: pd.Index) -> pd.Index:
return index


def maybe_cast_to_coords_dtype(label, coords_dtype):
if coords_dtype.kind == "f" and not isinstance(label, slice):
label = np.asarray(label, dtype=coords_dtype)
return label


def safe_cast_to_index(array: Any) -> pd.Index:
"""Given an array, safely cast it to a pandas.Index.
Expand Down
27 changes: 27 additions & 0 deletions xarray/tests/test_dataarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -928,6 +928,33 @@ def test_sel_dataarray_datetime(self):
result = array.sel(delta=slice(array.delta[0], array.delta[-1]))
assert_equal(result, array)

def test_sel_float(self):
data_values = np.arange(4)

# case coords are float32 and label is list of floats
float_values = [0.0, 0.111, 0.222, 0.333]
coord_values = np.asarray(float_values, dtype="float32")
array = DataArray(data_values, [("float32_coord", coord_values)])
expected = DataArray(data_values[1:3], [("float32_coord", coord_values[1:3])])
actual = array.sel(float32_coord=float_values[1:3])
# case coords are float16 and label is list of floats
coord_values_16 = np.asarray(float_values, dtype="float16")
expected_16 = DataArray(
data_values[1:3], [("float16_coord", coord_values_16[1:3])]
)
array_16 = DataArray(data_values, [("float16_coord", coord_values_16)])
actual_16 = array_16.sel(float16_coord=float_values[1:3])

# case coord, label are scalars
expected_scalar = DataArray(
data_values[2], coords={"float32_coord": coord_values[2]}
)
actual_scalar = array.sel(float32_coord=float_values[2])

assert_equal(expected, actual)
assert_equal(expected_scalar, actual_scalar)
assert_equal(expected_16, actual_16)

def test_sel_no_index(self):
array = DataArray(np.arange(10), dims="x")
assert_identical(array[0], array.sel(x=0))
Expand Down

0 comments on commit 097306b

Please sign in to comment.