{"database": "github", "table": "issues", "is_view": false, "human_description_en": "where state = \"open\", type = \"issue\" and user = 14808389 sorted by updated_at descending", "rows": [[2079089277, "I_kwDOAMm_X8577GJ9", 8607, "allow computing just a small number of variables", 14808389, "open", 0, null, null, 4, "2024-01-12T15:21:27Z", "2024-01-12T20:20:29Z", null, "MEMBER", null, null, null, "### Is your feature request related to a problem?\n\nI frequently find myself computing a handful of variables of a dataset (typically coordinates) and assigning them back to the dataset, and wishing we had a method / function that allowed that.\n\n### Describe the solution you'd like\n\nI'd imagine something like\r\n```python\r\nds.compute(variables=variable_names)\r\n```\r\nbut I'm undecided on whether that's a good idea (it might make `.compute` more complex?)\n\n### Describe alternatives you've considered\n\nSo far I've been using something like\r\n```python\r\nds.assign_coords({k: lambda ds: ds[k].compute() for k in variable_names})\r\nds.pipe(lambda ds: ds.merge(ds[variable_names].compute()))\r\n```\r\nbut both are not easy to type / understand (though having `.merge` take a callable would make this much easier). Also, the first option computes variables separately, which may not be ideal?\n\n### Additional context\n\n_No response_", "{\"url\": \"https://api.github.com/repos/pydata/xarray/issues/8607/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", null, null, 13221727, "issue"], [1655290694, "I_kwDOAMm_X85iqbtG", 7721, "`as_shared_dtype` converts scalars to 0d `numpy` arrays if chunked `cupy` is involved", 14808389, "open", 0, null, null, 7, "2023-04-05T09:48:34Z", "2023-12-04T10:45:43Z", null, "MEMBER", null, null, null, "I tried to run `where` with chunked `cupy` arrays:\r\n```python\r\nIn [1]: import xarray as xr\r\n   ...: import cupy\r\n   ...: import dask.array as da\r\n   ...: \r\n   ...: arr = xr.DataArray(cupy.arange(4), dims=\"x\")\r\n   ...: mask = xr.DataArray(cupy.array([False, True, True, False]), dims=\"x\")\r\n```\r\nthis works:\r\n```python\r\nIn [2]: arr.where(mask)\r\nOut[2]: \r\n<xarray.DataArray (x: 4)>\r\narray([nan,  1.,  2., nan])\r\nDimensions without coordinates: x\r\n```\r\nthis fails:\r\n```python\r\nIn [4]: arr.chunk().where(mask).compute()\r\n---------------------------------------------------------------------------\r\nTypeError                                 Traceback (most recent call last)\r\nCell In[4], line 1\r\n----> 1 arr.chunk().where(mask).compute()\r\n\r\nFile ~/repos/xarray/xarray/core/dataarray.py:1095, in DataArray.compute(self, **kwargs)\r\n   1076 \"\"\"Manually trigger loading of this array's data from disk or a\r\n   1077 remote source into memory and return a new array. The original is\r\n   1078 left unaltered.\r\n   (...)\r\n   1092 dask.compute\r\n   1093 \"\"\"\r\n   1094 new = self.copy(deep=False)\r\n-> 1095 return new.load(**kwargs)\r\n\r\nFile ~/repos/xarray/xarray/core/dataarray.py:1069, in DataArray.load(self, **kwargs)\r\n   1051 def load(self: T_DataArray, **kwargs) -> T_DataArray:\r\n   1052     \"\"\"Manually trigger loading of this array's data from disk or a\r\n   1053     remote source into memory and return this array.\r\n   1054 \r\n   (...)\r\n   1067     dask.compute\r\n   1068     \"\"\"\r\n-> 1069     ds = self._to_temp_dataset().load(**kwargs)\r\n   1070     new = self._from_temp_dataset(ds)\r\n   1071     self._variable = new._variable\r\n\r\nFile ~/repos/xarray/xarray/core/dataset.py:752, in Dataset.load(self, **kwargs)\r\n    749 import dask.array as da\r\n    751 # evaluate all the dask arrays simultaneously\r\n--> 752 evaluated_data = da.compute(*lazy_data.values(), **kwargs)\r\n    754 for k, data in zip(lazy_data, evaluated_data):\r\n    755     self.variables[k].data = data\r\n\r\nFile ~/.local/opt/mambaforge/envs/xarray/lib/python3.10/site-packages/dask/base.py:600, in compute(traverse, optimize_graph, scheduler, get, *args, **kwargs)\r\n    597     keys.append(x.__dask_keys__())\r\n    598     postcomputes.append(x.__dask_postcompute__())\r\n--> 600 results = schedule(dsk, keys, **kwargs)\r\n    601 return repack([f(r, *a) for r, (f, a) in zip(results, postcomputes)])\r\n\r\nFile ~/.local/opt/mambaforge/envs/xarray/lib/python3.10/site-packages/dask/threaded.py:89, in get(dsk, keys, cache, num_workers, pool, **kwargs)\r\n     86     elif isinstance(pool, multiprocessing.pool.Pool):\r\n     87         pool = MultiprocessingPoolExecutor(pool)\r\n---> 89 results = get_async(\r\n     90     pool.submit,\r\n     91     pool._max_workers,\r\n     92     dsk,\r\n     93     keys,\r\n     94     cache=cache,\r\n     95     get_id=_thread_get_id,\r\n     96     pack_exception=pack_exception,\r\n     97     **kwargs,\r\n     98 )\r\n    100 # Cleanup pools associated to dead threads\r\n    101 with pools_lock:\r\n\r\nFile ~/.local/opt/mambaforge/envs/xarray/lib/python3.10/site-packages/dask/local.py:511, in get_async(submit, num_workers, dsk, result, cache, get_id, rerun_exceptions_locally, pack_exception, raise_exception, callbacks, dumps, loads, chunksize, **kwargs)\r\n    509         _execute_task(task, data)  # Re-execute locally\r\n    510     else:\r\n--> 511         raise_exception(exc, tb)\r\n    512 res, worker_id = loads(res_info)\r\n    513 state[\"cache\"][key] = res\r\n\r\nFile ~/.local/opt/mambaforge/envs/xarray/lib/python3.10/site-packages/dask/local.py:319, in reraise(exc, tb)\r\n    317 if exc.__traceback__ is not tb:\r\n    318     raise exc.with_traceback(tb)\r\n--> 319 raise exc\r\n\r\nFile ~/.local/opt/mambaforge/envs/xarray/lib/python3.10/site-packages/dask/local.py:224, in execute_task(key, task_info, dumps, loads, get_id, pack_exception)\r\n    222 try:\r\n    223     task, data = loads(task_info)\r\n--> 224     result = _execute_task(task, data)\r\n    225     id = get_id()\r\n    226     result = dumps((result, id))\r\n\r\nFile ~/.local/opt/mambaforge/envs/xarray/lib/python3.10/site-packages/dask/core.py:119, in _execute_task(arg, cache, dsk)\r\n    115     func, args = arg[0], arg[1:]\r\n    116     # Note: Don't assign the subtask results to a variable. numpy detects\r\n    117     # temporaries by their reference count and can execute certain\r\n    118     # operations in-place.\r\n--> 119     return func(*(_execute_task(a, cache) for a in args))\r\n    120 elif not ishashable(arg):\r\n    121     return arg\r\n\r\nFile ~/.local/opt/mambaforge/envs/xarray/lib/python3.10/site-packages/dask/optimization.py:990, in SubgraphCallable.__call__(self, *args)\r\n    988 if not len(args) == len(self.inkeys):\r\n    989     raise ValueError(\"Expected %d args, got %d\" % (len(self.inkeys), len(args)))\r\n--> 990 return core.get(self.dsk, self.outkey, dict(zip(self.inkeys, args)))\r\n\r\nFile ~/.local/opt/mambaforge/envs/xarray/lib/python3.10/site-packages/dask/core.py:149, in get(dsk, out, cache)\r\n    147 for key in toposort(dsk):\r\n    148     task = dsk[key]\r\n--> 149     result = _execute_task(task, cache)\r\n    150     cache[key] = result\r\n    151 result = _execute_task(out, cache)\r\n\r\nFile ~/.local/opt/mambaforge/envs/xarray/lib/python3.10/site-packages/dask/core.py:119, in _execute_task(arg, cache, dsk)\r\n    115     func, args = arg[0], arg[1:]\r\n    116     # Note: Don't assign the subtask results to a variable. numpy detects\r\n    117     # temporaries by their reference count and can execute certain\r\n    118     # operations in-place.\r\n--> 119     return func(*(_execute_task(a, cache) for a in args))\r\n    120 elif not ishashable(arg):\r\n    121     return arg\r\n\r\nFile <__array_function__ internals>:180, in where(*args, **kwargs)\r\n\r\nFile cupy/_core/core.pyx:1723, in cupy._core.core._ndarray_base.__array_function__()\r\n\r\nFile ~/.local/opt/mambaforge/envs/xarray/lib/python3.10/site-packages/cupy/_sorting/search.py:211, in where(condition, x, y)\r\n    209 if fusion._is_fusing():\r\n    210     return fusion._call_ufunc(_where_ufunc, condition, x, y)\r\n--> 211 return _where_ufunc(condition.astype('?'), x, y)\r\n\r\nFile cupy/_core/_kernel.pyx:1287, in cupy._core._kernel.ufunc.__call__()\r\n\r\nFile cupy/_core/_kernel.pyx:160, in cupy._core._kernel._preprocess_args()\r\n\r\nFile cupy/_core/_kernel.pyx:146, in cupy._core._kernel._preprocess_arg()\r\n\r\nTypeError: Unsupported type <class 'numpy.ndarray'>\r\n```\r\nthis works again:\r\n```python\r\nIn [7]: arr.chunk().where(mask.chunk(), cupy.array(cupy.nan)).compute()\r\nOut[7]: \r\n<xarray.DataArray (x: 4)>\r\narray([nan,  1.,  2., nan])\r\nDimensions without coordinates: x\r\n```\r\nAnd other methods like `fillna` show similar behavior.\r\n\r\nI think the reason is that this: https://github.com/pydata/xarray/blob/d4db16699f30ad1dc3e6861601247abf4ac96567/xarray/core/duck_array_ops.py#L195 is not sufficient to detect `cupy` beneath other layers of duckarrays (most commonly `dask`, `pint`, or both). In this specific case we could extend the condition to also match chunked `cupy` arrays (like `arr.cupy.is_cupy` does, but using `is_duck_dask_array`), but this will still break for other duckarray layers or if `dask` is not involved, and we're also in the process of moving away from special-casing `dask`. So short of asking `cupy` to treat 0d arrays like scalars I'm not sure how to fix this.\r\n\r\ncc @jacobtomlinson", "{\"url\": \"https://api.github.com/repos/pydata/xarray/issues/7721/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", null, null, 13221727, "issue"], [1158378382, "I_kwDOAMm_X85FC3OO", 6323, "propagation of `encoding`", 14808389, "open", 0, null, null, 8, "2022-03-03T12:57:29Z", "2023-10-25T23:20:31Z", null, "MEMBER", null, null, null, "### What is your issue?\n\nWe frequently get bug reports related to `encoding` that can usually be fixed by clearing it or by overriding it using the `encoding` parameter of the `to_*` methods, e.g.\r\n- #4224\r\n- #4380\r\n- #4655\r\n- #5427\r\n- #5490\r\n- fsspec/kerchunk#130\r\n\r\nThere are also a few discussions with more background:\r\n- https://github.com/pydata/xarray/pull/5065#issuecomment-806154872\r\n- https://github.com/pydata/xarray/issues/1614\r\n- #5082\r\n- #5336\r\n\r\nWe discussed this in the meeting yesterday and as far as I can remember agreed that the current default behavior is not ideal and decided to investigate #5336: a `keep_encoding` option, similar to `keep_attrs`, that would be `True` (propagate `encoding`) by default but will be changed to `False` (drop `encoding` on any operation) in the future.\r\n\r\ncc @rabernat, @shoyer", "{\"url\": \"https://api.github.com/repos/pydata/xarray/issues/6323/reactions\", \"total_count\": 2, \"+1\": 2, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", null, null, 13221727, "issue"], [683142059, "MDU6SXNzdWU2ODMxNDIwNTk=", 4361, "restructure the contributing guide", 14808389, "open", 0, null, null, 5, "2020-08-20T22:51:39Z", "2023-03-31T17:39:00Z", null, "MEMBER", null, null, null, "From #4355\r\n\r\n@max-sixty:\r\n> Stepping back on the contributing doc \u2014 I admit I haven't look at it in a while \u2014 I wonder whether we can slim it down a bit, for example by linking to other docs for generic tooling \u2014 I imagine we're unlikely to have the best docs on working with GH, for example. Or referencing our PR template rather than the (now out-of-date) PR checklist.\r\n\r\nWe could also add a docstring guide since the `numpydoc` guide does not cover every little detail (for example, `default` notation, type spec vs. type hint, space before the colon separating parameter names from types, no colon for parameters without types, etc.)", "{\"url\": \"https://api.github.com/repos/pydata/xarray/issues/4361/reactions\", \"total_count\": 1, \"+1\": 1, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", null, null, 13221727, "issue"], [1306795760, "I_kwDOAMm_X85N5B7w", 6793, "improve docstrings with examples and links", 14808389, "open", 0, null, null, 10, "2022-07-16T12:30:33Z", "2023-03-24T16:33:28Z", null, "MEMBER", null, null, null, "This is a (incomplete) checklist for #5816 to make it easier to find methods that are in need of examples and links to the narrative docs with further information (of course, changes to the docstrings of all other methods / functions part of the public API are also appreciated).\r\n\r\nGood examples explicitly construct small xarray objects to make it easier to follow (e.g. use `np.{ones,full,zeros}` or the `np.array` constructor instead of `np.random` / loading from files) and show both input and output of the function.\r\n\r\nUse\r\n```sh\r\npytest --doctest-modules xarray --ignore xarray/tests/\r\n```\r\nto verify the examples, or push to a PR to have the CI do it for you (note that you will have much quicker feedback locally though).\r\n\r\nTo easily generate the expected output install `pytest-accept` ([docs]()) in your dev environment and then run\r\n```\r\npytest --doctest-modules FILE_NAME --accept || true\r\n```\r\n\r\nTo link to other documentation pages we can use\r\n```python\r\n:doc:`project:label`\r\n    Description of the linked page\r\n```\r\nwhere we can leave out `project` if we link to somewhere within xarray's documentation. To figure out the label, we can either look at the source, search the output of `python -m sphinx.ext.intersphinx https://docs.xarray.dev/en/latest/objects.inv`, or use `sphobjinv` (install from PyPI):\r\n```sh\r\nsphobjinv search -su https://docs.xarray.dev/en/latest/ missing\r\n```\r\n\r\nTop-level functions:\r\n- [ ] `get_options`\r\n- [ ] `decode_cf`\r\n- [ ] `polyval`\r\n- [ ] `unify_chunks`\r\n- [ ] `infer_freq`\r\n- [ ] `date_range`\r\n\r\nI/O:\r\n- [ ] `load_dataarray`\r\n- [ ] `load_dataset`\r\n- [ ] `open_dataarray`\r\n- [ ] `open_dataset`\r\n- [ ] `open_mfdataset`\r\n\r\nContents:\r\n- [ ] `DataArray.assign_attrs`, `Dataset.assign_attrs`\r\n- [ ] `DataArray.expand_dims`, `Dataset.expand_dims`\r\n- [ ] `DataArray.drop_duplicates`, `Dataset.drop_duplicates`\r\n- [ ] `DataArray.drop_vars`, `Dataset.drop_vars`\r\n- [ ] `Dataset.drop_dims`\r\n- [ ] `DataArray.convert_calendar`, `Dataset.convert_calendar`\r\n- [ ] `DataArray.set_coords`, `Dataset.set_coords`\r\n- [ ] `DataArray.reset_coords`, `Dataset.reset_coords`\r\n\r\nComparisons:\r\n- [ ] `DataArray.equals`, `Dataset.equals`\r\n- [ ] `DataArray.identical`, `Dataset.identical`\r\n- [ ] `DataArray.broadcast_equals`, `Dataset.broadcast_equals`\r\n\r\nDask:\r\n- [ ] `DataArray.compute`, `Dataset.compute`\r\n- [ ] `DataArray.chunk`, `Dataset.chunk`\r\n- [ ] `DataArray.persist`, `Dataset.persist`\r\n\r\nMissing values:\r\n- [ ] `DataArray.bfill`, `Dataset.bfill`\r\n- [ ] `DataArray.ffill`, `Dataset.ffill`\r\n- [ ] `DataArray.fillna`, `Dataset.fillna`\r\n- [ ] `DataArray.dropna`, `Dataset.dropna`\r\n\r\nIndexing:\r\n- [ ] `DataArray.loc` (no docstring at all - came up in https://github.com/pydata/xarray/discussions/7528#discussion-4858556)\r\n- [ ] `DataArray.drop_isel`\r\n- [ ] `DataArray.drop_sel`\r\n- [ ] `DataArray.head`, `Dataset.head`\r\n- [ ] `DataArray.tail`, `Dataset.tail`\r\n- [ ] `DataArray.interp_like`, `Dataset.interp_like`\r\n- [ ] `DataArray.reindex_like`, `Dataset.reindex_like`\r\n- [ ] `Dataset.isel`\r\n\r\nAggregations:\r\n- [ ] `Dataset.argmax`\r\n- [ ] `Dataset.argmin`\r\n- [ ] `DataArray.cumsum`, `Dataset.cumsum` (intermediate to advanced)\r\n- [ ] `DataArray.cumprod`, `Dataset.cumprod` (intermediate to advanced)\r\n- [ ] `DataArray.reduce`, `Dataset.reduce`", "{\"url\": \"https://api.github.com/repos/pydata/xarray/issues/6793/reactions\", \"total_count\": 4, \"+1\": 4, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", null, null, 13221727, "issue"], [532696790, "MDU6SXNzdWU1MzI2OTY3OTA=", 3594, "support for units with pint", 14808389, "open", 0, null, null, 7, "2019-12-04T13:49:28Z", "2022-08-03T11:44:05Z", null, "MEMBER", null, null, null, "`pint`'s implementation of NEP-18 (see hgrecco/pint#905) is close enough so we can finally start working on the `pint` support (i.e. make the integration tests pass). This would be the list of tasks to get there:\r\n* integration tests:\r\n  - [x] implement integration tests for `DataArray`, `Dataset` and top-level functions (#3238, #3447, #3493)\r\n  - [x] add tests for `Variable` as discussed in #3493 (#3654)\r\n  - [x] clean up the current tests (#3600)\r\n  - [x] use the standard `assert_identical` and `assert_allclose` functions (#3611, #3643, #3654, #3706, #3975)\r\n  - [x] clean up the `TestVariable.test_pad` tests\r\n* actually get xarray to support units:\r\n  - [x] top-level functions (#3611)\r\n  - [x] `Variable` (#3706)\r\n    + `rolling_window` and `identical` need larger modifications\r\n  - [x] `DataArray` (#3643)\r\n  - [x] `Dataset`\r\n  - [x] silence all the `UnitStrippedWarnings` in the testsuite (#4163)\r\n  - [ ] try to get `nanprod` to work with quantities\r\n  - [x] add support for per variable fill values (#4165)\r\n  - [x] `repr` with units (#2773)\r\n  - [ ] type hierarchy (e.g. for `np.maximum(data_array, quantity)` vs `np.maximum(quantity, data_array)`) (#3950)\r\n* update the documentation\r\n   - [x] point to [pint-xarray](https://github.com/xarray-contrib/pint-xarray) (see #4530)\r\n   - [x] mention the requirement for `UnitRegistry(force_ndarray=True)` or `UnitRegistry(force_ndarray_like=True)` (see https://pint-xarray.readthedocs.io/en/stable/creation.html#attaching-units)\r\n   - [x] list the known issues (see https://github.com/pydata/xarray/pull/3643#issue-354872657 and https://github.com/pydata/xarray/pull/3643#issuecomment-602225731) (#4530):\r\n       + `pandas` (indexing)\r\n       + `bottleneck` (`bfill`, `ffill`)\r\n       + `scipy` (`interp`)\r\n       + `numbagg` (`rolling_exp`)\r\n       + `numpy.lib.stride_tricks.as_strided`: `rolling`\r\n       + `numpy.vectorize`: `interpolate_na`\r\n   - [x] ~update the install instructions (we can use standard `conda` / `pip` now)~ this should be done by `pint-xarray`", "{\"url\": \"https://api.github.com/repos/pydata/xarray/issues/3594/reactions\", \"total_count\": 14, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 14, \"rocket\": 0, \"eyes\": 0}", null, null, 13221727, "issue"], [1265366275, "I_kwDOAMm_X85La_UD", 6678, "exception groups", 14808389, "open", 0, null, null, 1, "2022-06-08T22:09:37Z", "2022-06-08T23:38:28Z", null, "MEMBER", null, null, null, "### What is your issue?\n\nAs I mentioned in the meeting today, we have a lot of features where the the exception group support from [PEP654](https://peps.python.org/pep-0654/) (which is scheduled for python 3.11 and consists of the class and a syntax change) might be useful. For example, we might want to collect all errors raised by `rename` in a exception group instead of raising them one-by-one.\r\n\r\nFor `python<=3.10` there's a [backport](https://github.com/agronholm/exceptiongroup) that contains the class and a workaround for the new syntax.", "{\"url\": \"https://api.github.com/repos/pydata/xarray/issues/6678/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", null, null, 13221727, "issue"], [624778130, "MDU6SXNzdWU2MjQ3NzgxMzA=", 4095, "merging non-dimension coordinates with the Dataset constructor", 14808389, "open", 0, null, null, 1, "2020-05-26T10:30:37Z", "2022-04-19T13:54:43Z", null, "MEMBER", null, null, null, "When adding two `DataArray` objects with different coordinates to a `Dataset`, a `MergeError` is raised even though one of the conflicting coords is a subset of the other. Merging dimension coordinates works so I'd expect associated non-dimension coordinates to work, too.\r\n\r\nThis fails:\r\n```python\r\nIn [1]: import xarray as xr\r\n   ...: import numpy as np\r\n\r\nIn [2]: a = np.linspace(0, 1, 10)\r\n   ...: b = np.linspace(-1, 0, 12)\r\n   ...:\r\n   ...: x_a = np.arange(10)\r\n   ...: x_b = np.arange(12)\r\n   ...:\r\n   ...: y_a = x_a * 1000\r\n   ...: y_b = x_b * 1000\r\n   ...:\r\n   ...: arr1 = xr.DataArray(data=a, coords={\"x\": x_a, \"y\": (\"x\", y_a)}, dims=\"x\")\r\n   ...: arr2 = xr.DataArray(data=b, coords={\"x\": x_b, \"y\": (\"x\", y_b)}, dims=\"x\")\r\n   ...:\r\n   ...: xr.Dataset({\"a\": arr1, \"b\": arr2})\r\n...\r\nMergeError: conflicting values for variable 'y' on objects to be combined. You can skip this check by specifying compat='override'.\r\n```\r\nWhile this works:\r\n```python\r\nIn [3]: a = np.linspace(0, 1, 10)\r\n   ...: b = np.linspace(-1, 0, 12)\r\n   ...: \r\n   ...: x_a = np.arange(10)\r\n   ...: x_b = np.arange(12)\r\n   ...: \r\n   ...: y_a = x_a * 1000\r\n   ...: y_b = x_b * 1000\r\n   ...:\r\n   ...: xr.Dataset({\r\n   ...:     \"a\": xr.DataArray(data=a, coords={\"x\": x_a}, dims=\"x\"),\r\n   ...:     \"b\": xr.DataArray(data=b, coords={\"x\": x_b}, dims=\"x\"),\r\n   ...: })\r\nOut[3]:\r\n<xarray.Dataset>\r\nDimensions:  (x: 12)\r\nCoordinates:\r\n  * x        (x) int64 0 1 2 3 4 5 6 7 8 9 10 11\r\nData variables:\r\n    a        (x) float64 0.0 0.1111 0.2222 0.3333 0.4444 ... 0.8889 1.0 nan nan\r\n    b        (x) float64 -1.0 -0.9091 -0.8182 -0.7273 ... -0.1818 -0.09091 0.0\r\n```\r\n\r\nI can work around this by calling:\r\n```python\r\nIn [4]: xr.merge([arr1.rename(\"a\").to_dataset(), arr2.rename(\"b\").to_dataset()])\r\nOut[4]: \r\n<xarray.Dataset>\r\nDimensions:  (x: 12)\r\nCoordinates:\r\n  * x        (x) int64 0 1 2 3 4 5 6 7 8 9 10 11\r\n    y        (x) float64 0.0 1e+03 2e+03 3e+03 ... 8e+03 9e+03 1e+04 1.1e+04\r\nData variables:\r\n    a        (x) float64 0.0 0.1111 0.2222 0.3333 0.4444 ... 0.8889 1.0 nan nan\r\n    b        (x) float64 -1.0 -0.9091 -0.8182 -0.7273 ... -0.1818 -0.09091 0.0\r\n```\r\nbut I think the `Dataset` constructor should be capable of that, too.", "{\"url\": \"https://api.github.com/repos/pydata/xarray/issues/4095/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", null, null, 13221727, "issue"], [539181896, "MDU6SXNzdWU1MzkxODE4OTY=", 3638, "load_store and dump_to_store", 14808389, "open", 0, null, null, 1, "2019-12-17T16:37:53Z", "2021-11-08T21:11:26Z", null, "MEMBER", null, null, null, "Continuing from #3602, `load_store` and `dump_to_store` look like they are old and unmaintained functions:\r\n* `load_store` is referenced once in `api.rst` (I assume the reference to `from_store` was to `load_store`), but never tested, used or mentioned anywhere else\r\n* `dump_to_store` is tested (and probably used), but never mentioned except from the section on backends\r\n\r\nwhat should we do with these? Are they obsolete and should be removed or just unmaintained (then we should properly document and test them).", "{\"url\": \"https://api.github.com/repos/pydata/xarray/issues/3638/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", null, null, 13221727, "issue"], [789106802, "MDU6SXNzdWU3ODkxMDY4MDI=", 4825, "clean up the API for renaming and changing dimensions / coordinates", 14808389, "open", 0, null, null, 5, "2021-01-19T15:11:55Z", "2021-09-10T15:04:14Z", null, "MEMBER", null, null, null, "From #4108:\r\n\r\nI wonder if it would be better to first \"reorganize\" all of the existing functions: we currently have `rename` (and `Dataset.rename_dims` / `Dataset.rename_vars`), `set_coords`, `reset_coords`, `set_index`, `reset_index` and `swap_dims`, which overlap partially. For example, the code sample from #4417 works if instead of\r\n```python\r\nds = ds.rename(b='x')\r\nds = ds.set_coords('x')\r\n```\r\nwe use\r\n```python\r\nds = ds.set_index(x=\"b\")\r\n```\r\nand something similar for the code sample in #4107.\r\n\r\nI believe we currently have these use cases (not sure if that list is complete, though):\r\n- rename a `DataArray` \u2192 `rename`\r\n- rename a existing variable to a name that is not yet in the object \u2192 `rename` / `Dataset.rename_vars` / `Dataset.rename_dims`\r\n- convert a data variable to a coordinate (not a dimension coordinate) \u2192 `set_coords`\r\n- convert a coordinate (not a dimension coordinate) to a data variable \u2192 `reset_coords`\r\n- swap a existing dimension coordinate with a coordinate (which may not exist) and rename the dimension \u2192 `swap_dims`\r\n- use a existing coordinate / data variable as a dimension coordinate (do not rename the dimension) \u2192 `set_index`\r\n- stop using a coordinate as dimension coordinate and append `_` to its name (do not rename the dimension) \u2192 `reset_index`\r\n- use two existing coordinates / data variables as a MultiIndex \u2192 `set_index`\r\n- stop using a MultiIndex as a dimension coordinate and use its levels as coordinates \u2192 `reset_index`\r\n\r\nSometimes, some of these can be emulated by combinations of others, for example:\r\n```python\r\n# x is a dimension without coordinates\r\nassert_identical(ds.set_index({\"x\": \"b\"}), ds.swap_dims({\"x\": \"b\"}).rename({\"b\": \"x\"}))\r\nassert_identical(ds.swap_dims({\"x\": \"b\"}), ds.set_index({\"x\": \"b\"}).rename({\"x\": \"b\"}))\r\n```\r\nand, with this PR:\r\n```python\r\nassert_identical(ds.set_index({\"x\": \"b\"}), ds.set_coords(\"b\").rename({\"b\": \"x\"}))\r\nassert_identical(ds.swap_dims({\"x\": \"b\"}), ds.rename({\"b\": \"x\"}))\r\n```\r\nwhich means that it would increase the overlap of `rename`, `set_index`, and `swap_dims`.\r\n\r\nIn any case I think we should add a guide which explains which method to pick in which situation (or extend `howdoi`).\r\n\r\n_Originally posted by @keewis in https://github.com/pydata/xarray/issues/4108#issuecomment-761907785_", "{\"url\": \"https://api.github.com/repos/pydata/xarray/issues/4825/reactions\", \"total_count\": 2, \"+1\": 2, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", null, null, 13221727, "issue"], [935531700, "MDU6SXNzdWU5MzU1MzE3MDA=", 5562, "hooks to \"prepare\" xarray objects for plotting", 14808389, "open", 0, null, null, 6, "2021-07-02T08:14:02Z", "2021-07-04T08:46:34Z", null, "MEMBER", null, null, null, "From https://github.com/xarray-contrib/pint-xarray/pull/61#discussion_r662485351\r\n\r\n`matplotlib` has a module called `matplotlib.units` which manages a mapping of types to hooks. This is then used to convert custom types to something `matplotlib` can work with, and to optionally add axis labels. For example, with `pint`:\r\n```python\r\nIn [9]: ureg = pint.UnitRegistry()\r\n   ...: ureg.setup_matplotlib()\r\n   ...:\r\n   ...: t = ureg.Quantity(np.arange(10), \"s\")\r\n   ...: v = ureg.Quantity(5, \"m / s\")\r\n   ...: x = v * t\r\n   ...: \r\n   ...: fig, ax = plt.subplots(1, 1)\r\n   ...: ax.plot(t, x)\r\n   ...: \r\n   ...: plt.show()\r\n```\r\nthis will plot the data without `UnitStrippedWarning`s and even attach the units as labels to the axis (the format is hard-coded in `pint` right now).\r\n\r\nWhile this is pretty neat there are some issues:\r\n- `xarray`'s plotting code converts to `masked_array`, dropping metadata on the duck array (which means `matplotlib` won't see the duck arrays)\r\n- we will end up overwriting the axis labels once the variable names are added (not sure if there's a way to specify a label format?)\r\n- it is `matplotlib` specific, which means we have to reimplement once we go through with the plotting entrypoints discussed in #3553 and #3640\r\n\r\nAll of this makes me wonder: should we try to maintain our own mapping of hooks which \"prepare\" the object based on the data's type? My initial idea would be that the hook function receives a `Dataset` or `DataArray` object and modifies it to convert the data to `numpy` arrays and optionally modifies the `attrs`.\r\n\r\nFor example for `pint` the hook would return the result of `.pint.dequantify()` but it could also be used to explicitly call `.get` on `cupy` arrays or `.todense` on `sparse` arrays.\r\n\r\nxref #5561", "{\"url\": \"https://api.github.com/repos/pydata/xarray/issues/5562/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", null, null, 13221727, "issue"], [589850951, "MDU6SXNzdWU1ODk4NTA5NTE=", 3917, "running numpy functions on xarray objects", 14808389, "open", 0, null, null, 1, "2020-03-29T18:17:29Z", "2021-07-04T02:00:22Z", null, "MEMBER", null, null, null, "In the `pint` integration tests I tried to also test calling numpy functions on xarray objects (we provide methods for all of them).\r\n\r\nSome of these functions, like `numpy.median`, `numpy.searchsorted` and `numpy.clip`, depend on `__array_function__` (i.e. not `__array_ufunc__`) to dispatch. However, neither `Dataset` nor `DataArray` (nor `Variable`, I think?) define these protocols (see #3643).\r\n\r\nShould we define `__array_function__` on xarray objects?", "{\"url\": \"https://api.github.com/repos/pydata/xarray/issues/3917/reactions\", \"total_count\": 3, \"+1\": 3, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", null, null, 13221727, "issue"], [674445594, "MDU6SXNzdWU2NzQ0NDU1OTQ=", 4321, "push inline formatting functions upstream", 14808389, "open", 0, null, null, 0, "2020-08-06T16:35:04Z", "2021-04-19T03:20:11Z", null, "MEMBER", null, null, null, "#4248 added a `_repr_inline_` [method](https://xarray.pydata.org/en/latest/internals.html#duck-arrays) duck arrays can use to customize their collapsed variable `repr`.\r\n\r\nWe currently also have `inline_dask_repr` and `inline_sparse_repr` which remove redundant information like `dtype` and `shape` from `dask` and `sparse` arrays.\r\n\r\nIn order to reduce the complexity of `inline_variable_array_repr`, we could try to push these functions upstream.", "{\"url\": \"https://api.github.com/repos/pydata/xarray/issues/4321/reactions\", \"total_count\": 2, \"+1\": 2, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", null, null, 13221727, "issue"], [675342733, "MDU6SXNzdWU2NzUzNDI3MzM=", 4324, "constructing nested inline reprs", 14808389, "open", 0, null, null, 9, "2020-08-07T23:25:31Z", "2021-04-19T03:20:01Z", null, "MEMBER", null, null, null, "While implementing the new `_repr_inline_` in xarray-contrib/pint-xarray#22, I realized that I designed that method with a single level of nesting in mind, e.g. `xarray(pint(x))` or `xarray(dask(x))`.\r\n\r\nFrom that PR:\r\n@keewis\r\n> thinking about this some more, this doesn't work for anything other than `numpy.ndarray` objects. For now I guess we could use the magnitude's `_repr_inline_` (falling back to `__repr__` if that doesn't exist) and only use `format_array_flat` if the magnitude is a `ndarray`.\r\n> \r\n> However, as we nest deeper (e.g. `xarray(pint(uncertainties(dask(sparse(cupy)))))` \u2013 for argument's sake, let's assume that this actually makes sense) this might break or become really complicated. Does anyone have any ideas how to deal with that?\r\n> \r\n> If I'm simply missing something we have that discussion here, otherwise I guess we should open a issue on `xarray`'s issue tracker.\r\n\r\n@jthielen\r\n> Yes, I agree that `format_array_flat` should probably just apply to magnitude being an `ndarray`.\r\n> \r\n> I think a cascading series of `_repr_inline_` should work for nested arrays, so long as\r\n> \r\n>     * the metadata of the higher nested objects is considered the priority (if not, then we're back to a fully managed solution to the likes of [dask/dask#5329](https://github.com/dask/dask/issues/5329))\r\n> \r\n>     * small max lengths are handled gracefully (i.e., a minimum where it is just like `Dask.Array(...)`, then `...`, then nothing)\r\n> \r\n>     * we're okay with the lowest arrays in large nesting chains not having any information show up in the inline repr (situation where there is not enough characters to even describe the full nesting has to be accounted for somehow)\r\n> \r\n>     * it can be adopted without too much complaint across the ecosystem\r\n> \r\n> \r\n> Assuming all this, then each layer of the nesting will reduce the max length of the inline repr string available to the layers below it, until a layer reaches a reasonable minimum where it \"gives up\". At least that's the natural design that I inferred from the simple `_repr_inline_(max_width)` API.\r\n> \r\n> All that being said, it might still be good to bring up on xarray's end since this is a more general issue with inline reprs of nested duck arrays, with nothing pint-specific other than it being the motivating use-case.\r\n\r\nHow should we deal with this?", "{\"url\": \"https://api.github.com/repos/pydata/xarray/issues/4324/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", null, null, 13221727, "issue"], [791277757, "MDU6SXNzdWU3OTEyNzc3NTc=", 4837, "expose _to_temp_dataset / _from_temp_dataset as semi-public API?", 14808389, "open", 0, null, null, 5, "2021-01-21T16:11:32Z", "2021-01-22T02:07:08Z", null, "MEMBER", null, null, null, "When writing accessors which behave the same for both `Dataset` and `DataArray`, it would be incredibly useful to be able to use `DataArray._to_temp_dataset` / `DataArray._from_temp_dataset` to deduplicate code. Is it safe to use those in external packages (like `pint-xarray`)?\r\n\r\nOtherwise I guess it would be possible to use\r\n```python\r\nname = da.name if da.name is None else \"__temp\"\r\ntemp_ds = da.to_dataset(name=name)\r\nnew_da = temp_ds[name]\r\nif da.name is None:\r\n    new_da = new_da.rename(da.name)\r\nassert_identical(da, new_da)\r\n```\r\nbut that seems less efficient.", "{\"url\": \"https://api.github.com/repos/pydata/xarray/issues/4837/reactions\", \"total_count\": 2, \"+1\": 2, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", null, null, 13221727, "issue"], [552896124, "MDU6SXNzdWU1NTI4OTYxMjQ=", 3711, "PseudoNetCDF tests failing randomly", 14808389, "open", 0, null, null, 6, "2020-01-21T14:01:49Z", "2020-03-23T20:32:32Z", null, "MEMBER", null, null, null, "The `py37-windows` CI seems to fail for newer PRs:\r\n```pytb\r\n_______________ TestPseudoNetCDFFormat.test_uamiv_format_write ________________\r\n\r\nself = <xarray.tests.test_backends.TestPseudoNetCDFFormat object at 0x000002E11FF2DC08>\r\n\r\n    def\ttest_uamiv_format_write(self):\r\n\tfmtkw =\t{\"format\": \"uamiv\"}\r\n\r\n\texpected = open_example_dataset(\r\n            \"example.uamiv\", engine=\"pseudonetcdf\", backend_kwargs=fmtkw\r\n\t)\r\n\twith self.roundtrip(\r\n\t    expected,\r\n            save_kwargs=fmtkw,\r\n\t    open_kwargs={\"backend_kwargs\": fmtkw},\r\n            allow_cleanup_failure=True,\r\n\t) as actual:\r\n>           assert_identical(expected, actual)\r\n\r\nxarray\\tests\\test_backends.py:3532:\r\n_ _ _ _\t_ _ _ _\t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _\t_ _ _ _\t_ _ _ _\t_ _ _ _\t_ _ _ _\r\nxarray\\core\\formatting.py:628: in diff_dataset_repr\r\n    summary.append(diff_attrs_repr(a.attrs, b.attrs, compat))\r\n_ _ _ _\t_ _ _ _\t_ _ _ _\t_ _ _ _\t_ _ _ _\t_ _ _ _\t_ _ _ _\t_ _ _ _\t_ _ _ _\t_ _ _ _\r\n\r\na_mapping = {'CPROJ': 0, 'FILEDESC': 'CAMx            ', 'FTYPE': 1, 'GDNAM': 'CAMx            ', ...}\r\nb_mapping = {'CPROJ': 0, 'FILEDESC': 'CAMx            ', 'FTYPE': 1, 'GDNAM': 'CAMx            ', ...}\r\ncompat = 'identical', title = 'Attributes'\r\nsummarizer = <function summarize_attr at 0x000002E1156813A8>, col_width = None\r\n\r\n    def _diff_mapping_repr(a_mapping, b_mapping, compat, title, summarizer, col_width=None):\r\n        def extra_items_repr(extra_keys, mapping, ab_side):\r\n            extra_repr = [summarizer(k, mapping[k], col_width) for k in extra_keys]\r\n            if extra_repr:\r\n                header = f\"{title} only on the {ab_side} object:\"\r\n                return [header] + extra_repr\r\n            else:\r\n                return []\r\n\r\n\ta_keys = set(a_mapping)\r\n        b_keys = set(b_mapping)\r\n\r\n        summary = []\r\n\r\n\tdiff_items = []\r\n\r\n        for k in a_keys & b_keys:\r\n\t    try:\r\n                # compare xarray variable\r\n                compatible = getattr(a_mapping[k], compat)(b_mapping[k])\r\n                is_variable = True\r\n            except AttributeError:\r\n                # compare attribute value\r\n                compatible = a_mapping[k] == b_mapping[k]\r\n                is_variable = False\r\n\r\n>           if not compatible:\r\nE           ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()\r\n```", "{\"url\": \"https://api.github.com/repos/pydata/xarray/issues/3711/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", null, null, 13221727, "issue"], [517195073, "MDU6SXNzdWU1MTcxOTUwNzM=", 3483, "assign_coords with mixed DataArray / array args removes coords", 14808389, "open", 0, null, null, 5, "2019-11-04T14:38:40Z", "2019-11-07T15:46:15Z", null, "MEMBER", null, null, null, "I'm not sure if using `assign_coords` to overwrite the data of coords is the best way to do so, but using mixed args (on current master) turns out to have surprising results:\r\n```python\r\n>>> obj = xr.DataArray(\r\n...     data=[6, 3, 4, 6],\r\n...     coords={\"x\": list(\"abcd\"), \"y\": (\"x\", range(4))},\r\n...     dims=\"x\",\r\n... )\r\n>>> obj\r\n<xarray.DataArray 'obj' (x: 4)>\r\narray([6, 3, 4, 6])\r\nCoordinates:\r\n  * x        (x) <U1 'a' 'b' 'c' 'd'\r\n    y        (x) int64 0 1 2 3\r\n>>> # works as expected\r\n>>> obj.assign_coords(coords={\"x\": list(\"efgh\"), \"y\": (\"x\", [0, 2, 4, 6])})\r\n<xarray.DataArray 'obj' (x: 4)>\r\narray([6, 3, 4, 6])\r\nCoordinates:\r\n  * x        (x) <U1 'e' 'f' 'g' 'h'\r\n    y        (x) int64 0 2 4 6\r\n>>> # works, too (same as .data / .values)\r\n>>> obj.assign_coords(coords={\r\n...     \"x\": obj.x.copy(data=list(\"efgh\")).variable,\r\n...     \"y\": (\"x\", [0, 2, 4, 6]),\r\n... })\r\n<xarray.DataArray 'obj' (x: 4)>\r\narray([6, 3, 4, 6])\r\nCoordinates:\r\n  * x        (x) <U1 'e' 'f' 'g' 'h'\r\n    y        (x) int64 0 2 4 6\r\n>>> # this drops \"y\"\r\n>>> obj.assign_coords(coords={\r\n...     \"x\": obj.x.copy(data=list(\"efgh\")),\r\n...     \"y\": (\"x\", [0, 2, 4, 6]),\r\n... })\r\n<xarray.DataArray 'obj' (x: 4)>\r\narray([6, 3, 4, 6])\r\nCoordinates:\r\n  * x        (x) <U1 'e' 'f' 'g' 'h'\r\n```\r\nPassing a `DataArray` for `y`, like `obj.y * 2` while also changing `x` (the type does not matter) always results in a `MergeError`:\r\n```python\r\n>>> obj.assign_coords(x=list(\"efgh\"), y=obj.y * 2)\r\nxarray.core.merge.MergeError: conflicting values for index 'x' on objects to be combined:\r\nfirst value: Index(['e', 'f', 'g', 'h'], dtype='object', name='x')\r\nsecond value: Index(['a', 'b', 'c', 'd'], dtype='object', name='x')\r\n```\r\n\r\nI would expect the result to be the same regardless of the type of the new coords.\r\n\r\n", "{\"url\": \"https://api.github.com/repos/pydata/xarray/issues/3483/reactions\", \"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", null, null, 13221727, "issue"]], "truncated": false, "filtered_table_rows_count": 17, "expanded_columns": [], "expandable_columns": [[{"column": "repo", "other_table": "repos", "other_column": "id"}, "name"], [{"column": "milestone", "other_table": "milestones", "other_column": "id"}, "title"], [{"column": "assignee", "other_table": "users", "other_column": "id"}, "login"], [{"column": "user", "other_table": "users", "other_column": "id"}, "login"]], "columns": ["id", "node_id", "number", "title", "user", "state", "locked", "assignee", "milestone", "comments", "created_at", "updated_at", "closed_at", "author_association", "active_lock_reason", "draft", "pull_request", "body", "reactions", "performed_via_github_app", "state_reason", "repo", "type"], "primary_keys": ["id"], "units": {}, "query": {"sql": "select id, node_id, number, title, user, state, locked, assignee, milestone, comments, created_at, updated_at, closed_at, author_association, active_lock_reason, draft, pull_request, body, reactions, performed_via_github_app, state_reason, repo, type from issues where \"state\" = :p0 and \"type\" = :p1 and \"user\" = :p2 order by updated_at desc limit 101", "params": {"p0": "open", "p1": "issue", "p2": "14808389"}}, "facet_results": {"state": {"name": "state", "type": "column", "hideable": false, "toggle_url": "/github/issues.json?state=open&type=issue&user=14808389", "results": [{"value": "open", "label": "open", "count": 17, "toggle_url": "http://xarray-datasette.fly.dev/github/issues.json?type=issue&user=14808389", "selected": true}], "truncated": false}, "repo": {"name": "repo", "type": "column", "hideable": false, "toggle_url": "/github/issues.json?state=open&type=issue&user=14808389", "results": [{"value": 13221727, "label": "xarray", "count": 17, "toggle_url": "http://xarray-datasette.fly.dev/github/issues.json?state=open&type=issue&user=14808389&repo=13221727", "selected": false}], "truncated": false}, "type": {"name": "type", "type": "column", "hideable": false, "toggle_url": "/github/issues.json?state=open&type=issue&user=14808389", "results": [{"value": "issue", "label": "issue", "count": 17, "toggle_url": "http://xarray-datasette.fly.dev/github/issues.json?state=open&user=14808389", "selected": true}], "truncated": false}}, "suggested_facets": [{"name": "comments", "toggle_url": "http://xarray-datasette.fly.dev/github/issues.json?state=open&type=issue&user=14808389&_facet=comments"}, {"name": "created_at", "type": "date", "toggle_url": "http://xarray-datasette.fly.dev/github/issues.json?state=open&type=issue&user=14808389&_facet_date=created_at"}, {"name": "updated_at", "type": "date", "toggle_url": "http://xarray-datasette.fly.dev/github/issues.json?state=open&type=issue&user=14808389&_facet_date=updated_at"}], "next": null, "next_url": null, "private": false, "allow_execute_sql": true, "query_ms": 47.48265305534005}