Skip to content

Commit 1bb61d9

Browse files
committed
fix dtype of index variables created from Index
1 parent 1250ccf commit 1bb61d9

File tree

2 files changed

+22
-12
lines changed

2 files changed

+22
-12
lines changed

xarray/core/indexes.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ def from_variables(cls, variables: Mapping[Hashable, "Variable"]):
169169

170170
obj = cls(var.data, dim)
171171

172-
data = PandasIndexingAdapter(obj.index)
172+
data = PandasIndexingAdapter(obj.index, dtype=var.dtype)
173173
index_var = IndexVariable(
174174
dim, data, attrs=var.attrs, encoding=var.encoding, fastpath=True
175175
)
@@ -314,12 +314,15 @@ def from_variables(cls, variables: Mapping[Hashable, "Variable"]):
314314

315315
@classmethod
316316
def from_pandas_index(cls, index: pd.MultiIndex, dim: Hashable):
317-
levels = [
318-
name if name is not None else f"{dim}_level_{i}"
319-
for i, name in enumerate(index.names)
320-
]
321-
index = index.rename(levels)
322-
index_vars = _create_variables_from_multiindex(index, dim)
317+
level_meta = {}
318+
for i, idx in enumerate(index.levels):
319+
name = idx.name or f"{dim}_level_{i}"
320+
level_meta[name] = {"dtype": idx.dtype}
321+
322+
index = index.rename(level_meta.keys())
323+
index_vars = _create_variables_from_multiindex(
324+
index, dim, level_meta=level_meta
325+
)
323326
return cls(index, dim), index_vars
324327

325328
def query(self, labels, method=None, tolerance=None):

xarray/tests/test_indexes.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,15 @@ def test_constructor(self):
2828
assert index.dim == "x"
2929

3030
def test_from_variables(self):
31+
# pandas has only Float64Index but variable dtype should be preserved
32+
data = np.array([1.1, 2.2, 3.3], dtype=np.float32)
3133
var = xr.Variable(
32-
"x", [1, 2, 3], attrs={"unit": "m"}, encoding={"dtype": np.int32}
34+
"x", data, attrs={"unit": "m"}, encoding={"dtype": np.float64}
3335
)
3436

3537
index, index_vars = PandasIndex.from_variables({"x": var})
3638
xr.testing.assert_identical(var.to_index_variable(), index_vars["x"])
39+
assert index_vars["x"].dtype == var.dtype
3740
assert index.dim == "x"
3841
assert index.index.equals(index_vars["x"].to_index())
3942

@@ -166,16 +169,20 @@ def test_from_variables(self):
166169
PandasMultiIndex.from_variables({"level1": v_level1, "level3": v_level3})
167170

168171
def test_from_pandas_index(self):
169-
pd_idx = pd.MultiIndex.from_arrays([[1, 2, 3], [4, 5, 6]], names=("foo", "bar"))
172+
foo_data = np.array([0, 0, 1], dtype="int")
173+
bar_data = np.array([1.1, 1.2, 1.3], dtype="float64")
174+
pd_idx = pd.MultiIndex.from_arrays([foo_data, bar_data], names=("foo", "bar"))
170175

171176
index, index_vars = PandasMultiIndex.from_pandas_index(pd_idx, "x")
172177

173178
assert index.dim == "x"
174-
assert index.index is pd_idx
179+
assert index.index.equals(pd_idx)
175180
assert index.index.names == ("foo", "bar")
176181
xr.testing.assert_identical(index_vars["x"], IndexVariable("x", pd_idx))
177-
xr.testing.assert_identical(index_vars["foo"], IndexVariable("x", [1, 2, 3]))
178-
xr.testing.assert_identical(index_vars["bar"], IndexVariable("x", [4, 5, 6]))
182+
xr.testing.assert_identical(index_vars["foo"], IndexVariable("x", foo_data))
183+
xr.testing.assert_identical(index_vars["bar"], IndexVariable("x", bar_data))
184+
assert index_vars["foo"].dtype == foo_data.dtype
185+
assert index_vars["bar"].dtype == bar_data.dtype
179186

180187
def test_query(self):
181188
index = PandasMultiIndex(

0 commit comments

Comments
 (0)