Skip to content

Commit 097306b

Browse files
HasanAhmadQ7shoyer
authored andcommitted
BUG fix +test .sel method gives error with float32 values (#3153)
* 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
1 parent 362ae55 commit 097306b

File tree

4 files changed

+39
-1
lines changed

4 files changed

+39
-1
lines changed

doc/whats-new.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ Bug fixes
6262
- XFAIL several tests which are expected to fail on ARM systems
6363
due to a ``datetime`` issue in NumPy (:issue:`2334`).
6464
By `Graham Inggs <https://github.com/ginggs>`_.
65+
- Fix KeyError that arises when using .sel method with float values
66+
different from coords float type (:issue:`3137`).
67+
By `Hasan Ahmad <https://github.com/HasanAhmadQ7>`_.
6568
- Fixed bug in ``combine_by_coords()`` causing a `ValueError` if the input had
6669
an unused dimension with coordinates which were not monotonic (:issue:`3150`).
6770
By `Tom Nicholas <http://github.com/TomNicholas>`_.

xarray/core/indexing.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from . import duck_array_ops, nputils, utils
1212
from .npcompat import DTypeLike
1313
from .pycompat import dask_array_type, integer_types
14-
from .utils import is_dict_like
14+
from .utils import is_dict_like, maybe_cast_to_coords_dtype
1515

1616

1717
def expanded_indexer(key, ndim):
@@ -269,6 +269,8 @@ def remap_label_indexers(data_obj, indexers, method=None, tolerance=None):
269269
)
270270
pos_indexers[dim] = label
271271
else:
272+
coords_dtype = data_obj.coords[dim].dtype
273+
label = maybe_cast_to_coords_dtype(label, coords_dtype)
272274
idxr, new_idx = convert_label_indexer(index, label, dim, method, tolerance)
273275
pos_indexers[dim] = idxr
274276
if new_idx is not None:

xarray/core/utils.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,12 @@ def _maybe_cast_to_cftimeindex(index: pd.Index) -> pd.Index:
8585
return index
8686

8787

88+
def maybe_cast_to_coords_dtype(label, coords_dtype):
89+
if coords_dtype.kind == "f" and not isinstance(label, slice):
90+
label = np.asarray(label, dtype=coords_dtype)
91+
return label
92+
93+
8894
def safe_cast_to_index(array: Any) -> pd.Index:
8995
"""Given an array, safely cast it to a pandas.Index.
9096

xarray/tests/test_dataarray.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -928,6 +928,33 @@ def test_sel_dataarray_datetime(self):
928928
result = array.sel(delta=slice(array.delta[0], array.delta[-1]))
929929
assert_equal(result, array)
930930

931+
def test_sel_float(self):
932+
data_values = np.arange(4)
933+
934+
# case coords are float32 and label is list of floats
935+
float_values = [0.0, 0.111, 0.222, 0.333]
936+
coord_values = np.asarray(float_values, dtype="float32")
937+
array = DataArray(data_values, [("float32_coord", coord_values)])
938+
expected = DataArray(data_values[1:3], [("float32_coord", coord_values[1:3])])
939+
actual = array.sel(float32_coord=float_values[1:3])
940+
# case coords are float16 and label is list of floats
941+
coord_values_16 = np.asarray(float_values, dtype="float16")
942+
expected_16 = DataArray(
943+
data_values[1:3], [("float16_coord", coord_values_16[1:3])]
944+
)
945+
array_16 = DataArray(data_values, [("float16_coord", coord_values_16)])
946+
actual_16 = array_16.sel(float16_coord=float_values[1:3])
947+
948+
# case coord, label are scalars
949+
expected_scalar = DataArray(
950+
data_values[2], coords={"float32_coord": coord_values[2]}
951+
)
952+
actual_scalar = array.sel(float32_coord=float_values[2])
953+
954+
assert_equal(expected, actual)
955+
assert_equal(expected_scalar, actual_scalar)
956+
assert_equal(expected_16, actual_16)
957+
931958
def test_sel_no_index(self):
932959
array = DataArray(np.arange(10), dims="x")
933960
assert_identical(array[0], array.sel(x=0))

0 commit comments

Comments
 (0)