Cannot reindex onto a stacked MultiIndex via indexers — only reindex_like works
还没有人认领这个 Issue。
评估
调研方向
首先运行提供的最小示例,并通过 xarray 的对齐机制跟踪 DataArray.reindex、reindex_like 和 Coordinates.from_pandas_multiindex。该 issue 未指定源文件或测试;当至少一种直接 reindex 形式接受目标 MultiIndex,并产生与 reindex_like(template) 相同的填充结果时,即视为完成。
由索引模型根据 Issue 内容生成。
描述
What happened?
Reindexing a DataArray whose dimension is backed by a stacked pd.MultiIndex onto a different MultiIndex (e.g. the full index, where the array covers a subset) fails for every indexer form:
- a raw
pd.MultiIndexas indexer value →ValueError: unmatched keys found in indexes and variables: {'kind', 'city'} - a
Coordinates.from_pandas_multiindex(...)mapping as indexers →AlignmentError: Indexer has dimensions ('station',) that are different from that to be indexed along 'city' - the MultiIndex-backed coordinate variable as indexer value → same
ValueErroras 1.
The only working path is reindex_like(template) where the template is a throwaway object constructed with Coordinates.from_pandas_multiindex — which shows the operation itself is supported by the alignment machinery; it's only unreachable through the reindex() indexers API.
What did you expect to happen?
At least one of the indexer forms (ideally 1. and 3.) to be equivalent to the reindex_like call: a pd.MultiIndex indexer should be expanded into the dimension index plus its level coordinates internally, the same way Coordinates.from_pandas_multiindex and reindex_like do.
Minimal Complete Verifiable Example
import numpy as np
import pandas as pd
import xarray as xr
from xarray import Coordinates, DataArray
# A DataArray indexed by a stacked MultiIndex dimension "station",
# covering a SUBSET of the full index
full = pd.MultiIndex.from_product([[1, 2], ["a", "b"]], names=("city", "kind"))
subset = pd.MultiIndex.from_tuples([(1, "a"), (2, "b")], names=("city", "kind"))
da = DataArray(
[10.0, 20.0],
coords=Coordinates.from_pandas_multiindex(subset, "station"),
dims="station",
)
# GOAL: conform `da` to the full MultiIndex, filling missing entries.
# 1) raw pd.MultiIndex as indexer
try:
da.reindex({"station": full}, fill_value=0.0)
except Exception as e:
print(f"1) raw pd.MultiIndex indexer:\n {type(e).__name__}: {e}\n")
# 2) Coordinates.from_pandas_multiindex as the indexers mapping
try:
da.reindex(Coordinates.from_pandas_multiindex(full, "station"), fill_value=0.0)
except Exception as e:
print(f"2) Coordinates as indexers:\n {type(e).__name__}: {e}\n")
# 3) the MultiIndex-backed coordinate variable as indexer
full_coords = Coordinates.from_pandas_multiindex(full, "station")
try:
da.reindex({"station": full_coords["station"]}, fill_value=0.0)
except Exception as e:
print(f"3) MI-backed coord variable indexer:\n {type(e).__name__}: {e}\n")
# 4) reindex_like with a template object carrying the same Coordinates -> WORKS
template = DataArray(np.zeros(len(full)), coords=full_coords, dims="station")
result = da.reindex_like(template, fill_value=0.0)
print("4) reindex_like(template) works:")
print(result.to_series())
MVCE confirmation
- Minimal example — the example is as focused as reasonably possible to demonstrate the underlying issue in xarray.
- Complete example — the example is self-contained, including all data and the text of any traceback.
- Verifiable example — the example runs when copied & pasted into an empty Python session (output included below).
- New issue — a search of GitHub Issues suggests this is not a duplicate (#10347 is related but covers a level-of-MultiIndex coord as indexer, fixed in 2025.x; this is about the stacked MultiIndex dimension itself).
Relevant log output
1) raw pd.MultiIndex indexer:
ValueError: unmatched keys found in indexes and variables: {'kind', 'city'}
2) Coordinates as indexers:
AlignmentError: Indexer has dimensions ('station',) that are different from that to be indexed along 'city'
3) MI-backed coord variable indexer:
ValueError: unmatched keys found in indexes and variables: {'kind', 'city'}
4) reindex_like(template) works:
city kind
1 a 10.0
b 0.0
2 a 0.0
b 20.0
dtype: float64
Anything else we need to know?
Use case: in linopy (and PyPSA's multi-investment models, where snapshots are a (period, timestep) MultiIndex), we conform user input to a target index that exists only as coordinates — there is no object to reindex_like against, so we have to construct a throwaway template just to perform the reindex.
This issue was discovered and written up with AI assistance (Claude Code); the repro and outputs are verified on a real environment.
Environment
INSTALLED VERSIONS
------------------
commit: None
python: 3.13.2 (main, Mar 17 2025, 21:26:38) [Clang 20.1.0 ]
python-bits: 64
OS: Darwin
OS-release: 25.2.0
machine: arm64
processor: arm
byteorder: little
LC_ALL: None
LANG: C.UTF-8
LOCALE: (None, 'UTF-8')
libhdf5: 1.14.6
libnetcdf: 4.9.3
xarray: 2026.4.0
pandas: 2.3.3
numpy: 1.26.4
scipy: 1.17.1
netCDF4: 1.7.4
cftime: 1.6.5
bottleneck: 1.6.0
dask: 2026.3.0
fsspec: 2026.4.0
- 主要语言
- Python
- 星标
- 4.2k
- 派生
- 1.4k
- 平均合并
- 2 天 15 小时
- 30 天内合并 PR
- 14
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
pydata/xarray 的其他 Issue
-
bug needs triage
难度 2/5 1-3 小时 新手友好度 68/100
-
难度 2/5 1-3 小时 新手友好度 85/100
-
难度 2/5 1-3 小时 新手友好度 76/100
-
bug needs triage
难度 2/5 1-3 小时 新手友好度 72/100
-
bug needs triage
难度 1/5 1-3 小时 新手友好度 82/100
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 88/100
-
难度 2/5 1-3 小时 新手友好度 82/100
-
难度 2/5 1-3 小时 新手友好度 78/100
-
enhancement
难度 2/5 1-3 小时 新手友好度 72/100
-
难度 2/5 1-3 小时 新手友好度 74/100