-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rename_vars
followed by swap_dims
and merge
causes swapped dim to reappear
#8646
Comments
Thanks for opening your first issue here at xarray! Be sure to follow the issue template! |
Thanks for the excellent issue @brendan-m-murphy . This is really surprising. If we look at these two objects, there's no [ins] In [3]: ds1_swap
Out[3]:
<xarray.Dataset>
Dimensions: (x: 2, z: 2)
Coordinates:
* x (x) int64 1 2
* z (z) int64 1 2
Data variables:
A (x, z) int64 0 1 2 3
B (x, z) int64 4 5 6 7
[ins] In [4]: ds2_swap
Out[4]:
<xarray.Dataset>
Dimensions: (x: 2, z: 2)
Coordinates:
* x (x) int64 1 2
* z (z) int64 1 2
Data variables:
C (x, z) int64 0 1 2 3
D (x, z) int64 4 5 6 7 But then if we merge them, a [ins] In [2]: xr.merge([ds1_swap, ds2_swap])
Out[2]:
<xarray.Dataset>
Dimensions: (x: 2, z: 2, y: 2) # where does this come from?
Coordinates:
* x (x) int64 1 2
* z (y) int64 1 2
Dimensions without coordinates: y
Data variables:
A (x, z) int64 0 1 2 3
B (x, z) int64 4 5 6 7
C (x, z) int64 0 1 2 3
D (x, z) int64 4 5 6 7 Where does the I think we should be quite worried about this — one of the wonderful things about xarray is that it's not doing surprising things — the repr of the object is effectively a full representation of it. But this violates that — somewhere there's a IIRC @benbovy has helped fix similar things in the past, hope it's OK to tag you in case you have any ideas. |
It might be worth looking at the I suspect a bug in |
Thanks for the response + the idea. It's indeed on the [nav] In [32]: ds2_swap._indexes['z'].dim
Out[32]: 'y' Should the |
Good catch. A possible fix would be class Dataset(...):
def swap_dims(self, ...):
...
for current_name, current_variable in self.variables.items():
...
if current_name in result_dims:
...
if current_name in self._indexes:
indexes[current_name] = self._indexes[current_name]
indexes[current_name].dim = dims_dict[current_name] # update the index dim here
variables[current_name] = var
else:
...
else:
... However, this fix works only in the case of a single Maybe it's time to deprecate |
Is |
To my knowledge it doesn't allow doing more than what we can do now with those other methods, it only adds some confusion :). |
if these two: ds = xr.Dataset(coords={"x": ("x", [0, 1]), "y": ("x", [-1, 1])})
ds.swap_dims({"x": "y"})
ds.rename_dims({"x": "y"}).set_xindex("y").drop_indexes(["x"]) do the same thing, could we just make the former use the latter as implementation (obviously adapted to allow renaming multiple dimensions at the same time)? I don't think we'd even need a deprecation cycle for that. |
Ah yes probably, although not sure that |
If you're not chaining In any case, I'm just saying that if we are to drop |
In my case, I'm using Anyway, it doesn't seem like you'd be able to replace |
interestingly, |
Anecdotally, I've seen |
Ah okay, I probably tried As you say, for
I get the expected result when I merge
but the dimension of
(Also I just realised |
I might miss the high-level picture here. I thought that This workaround is not needed anymore since we support indexes for non-dimension coordinates. And for renaming a dimension coordinate there is indeed @dcherian did you see |
This reverts commit 4a958dc.
* Stateful tests with Dataset * Disable check_default_indexes when needed * Add Zarr roundtrip * Randomize dimension choice * Fix a bug * Add reset_index * Add stack, unstack * [revert] Disable Zarr till we control attrs strategy * Try making unique names * Share names strategy to ensure uniques? * cleanup * Try sharing strategies better * Fix endianness * Better swap_dims * More improvements * WIP * Drop duplicates before unstacking * Add reset_index * Better duplicate assumption * Move * Fix reset_index * Skip if hypothesis not installed * Better precondition around reset_index * Note * Try a bundle * Use unique_subset_of * Use Bundles more * Add index_variables strategy * Small improvement * fix * Use st.shared * Revert "Use st.shared" This reverts commit 50f6030. * fix unstacking * cleanup * WIP * Remove bundles * Fixes * Add hypothesis cache to CI * Prevent index variables with NaNs, infs * [revert] * Always save hypothesis cache * Expand dtypes * Add invariant check for #8646 * Add drop_dims * Add create_index to stack * Generalize a bit * limit number of indexes to stack * Fix endianness? * uniquify drop_dims * Avoid NaTs in index vars HypothesisWorks/hypothesis#3943 * Guard swap_dims * Revert "Add invariant check for #8646" This reverts commit 4a958dc. * Add drop_indexes * Add assign_coords * Fix max_period for pandas timedelta * Add xfailed test * Add notes * Skip timedelta indexes * to_zarr * small tweaks * Remove NaT assume * Revert "[revert]" This reverts commit 6a38e27. * Add hypothesis workflow * Swtich out * fix * Use st.builds * cleanup * Add initialize * review feedback
I've tried re-implementing Regarding this issue, the other possible fix in #8646 (comment) is limited to pandas single indexes. As an alternative to those fixes and deprecating ds = xr.Dataset(coords={"x": ("x", [0, 1])})
renamed = ds.rename_vars({"x": "y"})
renamed.swap_dims({"x": "y"})
# ValueError: swap_dims only works with dimension coordinates but found coordinate "y" with dimension "x" This will not fix the issue here but at least it will provide a clear error message instead of weird issues (old dimension appearing from nowhere) later on. Workarounds exist like |
What happened?
I wanted to rename a dimension coordinate for two datasets before merging:
ds = ds.rename_vars(y="z").swap_dims(y="z")
, and the same for the second data set. After merging the datasets, the merged result has the dimension "y" in addition to "z".Swapping the order of
rename_vars
andswap_dims
before merging works in that "y" does not reappear, but then "z" is listed as a non-dimension coordinate.Doing
rename_vars
followed byswap_dims
/after/ merging gives the result I wanted, but if I merge again, the same issue occurs.My current solution is to only rename dimension coordinates before saving to netCDF.
What did you expect to happen?
Merging two datasets with the same coordinates and dimensions (but different data variables) should result in a single dataset with all of the data variables from the two datasets and exactly the same coordinates and dimensions.
Minimal Complete Verifiable Example
MVCE confirmation
Relevant log output
No response
Anything else we need to know?
No response
Environment
The MVCE works in all venvs I've tried including:
INSTALLED VERSIONS
commit: None
python: 3.10.13 (main, Nov 10 2023, 15:02:19) [GCC 11.4.0]
python-bits: 64
OS: Linux
OS-release: 6.5.0-14-generic
machine: x86_64
processor: x86_64
byteorder: little
LC_ALL: None
LANG: en_GB.UTF-8
LOCALE: ('en_GB', 'UTF-8')
libhdf5: 1.12.2
libnetcdf: 4.9.3-development
xarray: 2023.11.0
pandas: 1.5.3
numpy: 1.26.2
scipy: 1.11.4
netCDF4: 1.6.5
pydap: None
h5netcdf: 1.3.0
h5py: 3.10.0
Nio: None
zarr: None
cftime: 1.6.3
nc_time_axis: 1.4.1
iris: None
bottleneck: None
dask: 2023.12.0
distributed: None
matplotlib: 3.8.2
cartopy: 0.22.0
seaborn: 0.13.0
numbagg: None
fsspec: 2023.12.1
cupy: None
pint: None
sparse: 0.15.1
flox: None
numpy_groupies: None
setuptools: 69.0.2
pip: 23.3.1
conda: None
pytest: 7.4.3
mypy: None
IPython: 8.18.1
sphinx: None
/home/brendan/Documents/inversions/.pymc_venv/lib/python3.10/site-packages/_distutils_hack/init.py:33: UserWarning: Setuptools is replacing distutils.
warnings.warn("Setuptools is replacing distutils.")
INSTALLED VERSIONS
commit: None
python: 3.9.7 (default, Sep 16 2021, 13:09:58)
[GCC 7.5.0]
python-bits: 64
OS: Linux
OS-release: 3.10.0-1160.81.1.el7.x86_64
machine: x86_64
processor: x86_64
byteorder: little
LC_ALL: None
LANG: en_GB.UTF-8
LOCALE: ('en_GB', 'UTF-8')
libhdf5: None
libnetcdf: None
xarray: 2024.1.0
pandas: 2.2.0
numpy: 1.26.3
scipy: None
netCDF4: None
pydap: None
h5netcdf: None
h5py: None
Nio: None
zarr: None
cftime: None
nc_time_axis: None
iris: None
bottleneck: None
dask: None
distributed: None
matplotlib: None
cartopy: None
seaborn: None
numbagg: None
fsspec: None
cupy: None
pint: None
sparse: None
flox: None
numpy_groupies: None
setuptools: 69.0.3
pip: 23.3.2
conda: None
pytest: None
mypy: None
IPython: 8.18.1
sphinx: None
The text was updated successfully, but these errors were encountered: