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
714228717,MDExOlB1bGxSZXF1ZXN0NDk3MzcyNTY2,4484,xarray.map,1277781,closed,0,,,12,2020-10-04T04:11:29Z,2023-10-16T18:54:19Z,2023-10-16T18:54:19Z,CONTRIBUTOR,,0,pydata/xarray/pulls/4484,"<!-- Feel free to remove check-list items aren't relevant to your change -->

UPDATE:
Please let me know whether this PR can be considered to be merged.
If not I won't bother trying to fix failed tests such as: 

> would reformat /home/vsts/work/1/s/xarray/core/map.py
> would reformat /home/vsts/work/1/s/xarray/core/dataset.py
> would reformat /home/vsts/work/1/s/xarray/tests/test_map.py
> Oh no! 💥 💔 💥

Thanks

--------
 - [x] Tests added
 - [x] User visible changes (including notable bug fixes) are documented in `whats-new.rst`
 - [x] New functions/methods are listed in `api.rst`

I implemented the top-level xarray.map function.
It is a generalization of the Dataset.map method for those functions which take more than one DataArray as input.
The function will be applied to the intersection of the variables in the datasets.

E.g: 
```
f = lambda a, b: b-a
map([ds1, ds2], f)
```
More details in the docstring.

(I probably messed up something with git as the commits listed below also include my earlier commits not related to this PR. But the list of files is clean, it only includes what I'd like to merge)","{""url"": ""https://api.github.com/repos/pydata/xarray/issues/4484/reactions"", ""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",,,13221727,pull
423742774,MDU6SXNzdWU0MjM3NDI3NzQ=,2835,Dataset.copy(deep=True) does not deepcopy .attrs,1277781,closed,0,,,12,2019-03-21T13:58:03Z,2022-09-29T16:36:52Z,2022-09-29T16:36:52Z,CONTRIBUTOR,,,,But it would be expected (at least by me) that it does.,"{""url"": ""https://api.github.com/repos/pydata/xarray/issues/2835/reactions"", ""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",,completed,13221727,issue
623131373,MDU6SXNzdWU2MjMxMzEzNzM=,4087,Bug in conversion frompd.series in 0.15.1,1277781,closed,0,,,3,2020-05-22T11:04:11Z,2020-05-22T11:59:40Z,2020-05-22T11:29:46Z,CONTRIBUTOR,,,,"Bug in conversion frompd.series 


#### MCVE Code Sample
<!-- In order for the maintainers to efficiently understand and prioritize issues, we ask you post a ""Minimal, Complete and Verifiable Example"" (MCVE): http://matthewrocklin.com/blog/work/2018/02/28/minimal-bug-reports -->

```python
import pandas as pd
import xarray as xr

data3 = pd.DataFrame([(1,  2, 1), (2, 2, 1)],columns=['x', 'B', 'A'])
data3 = data3.set_index(['x'])
data3.rename_axis('tag', axis=1, inplace=True)
data3 = data3.stack()
print(data3)
print(xr.DataArray.from_series(data3).sel(tag='B'))
```

#### Expected Output
[2,2]

#### Problem Description
The same code gives the expected output in xarray 0.14.1
Also works correctly if ""tag"" dimension is properly sorted during DataFrame cretion.


#### Versions

<details><summary>Output of <tt>xr.show_versions()</tt></summary>

INSTALLED VERSIONS
------------------
commit: None
python: 3.6.7 | packaged by conda-forge | (default, Jul  2 2019, 02:18:42) 
[GCC 7.3.0]
python-bits: 64
OS: Linux
OS-release: 4.1.12-124.38.1.el7uek.x86_64
machine: x86_64
processor: x86_64
byteorder: little
LC_ALL: en_US.utf8
LANG: en_US.utf8
LOCALE: en_US.UTF-8
libhdf5: 1.10.4
libnetcdf: 4.6.3

xarray: 0.15.1
pandas: 0.25.0
numpy: 1.17.0
scipy: 1.3.0
netCDF4: 1.5.3
pydap: None
h5netcdf: None
h5py: 2.7.1
Nio: None
zarr: None
cftime: 1.1.3
nc_time_axis: None
PseudoNetCDF: None
rasterio: None
cfgrib: None
iris: None
bottleneck: None
dask: 2.16.0
distributed: None
matplotlib: 3.1.1
cartopy: None
seaborn: 0.9.0
numbagg: None
setuptools: 46.3.1
pip: 19.2.1
conda: 4.8.3
pytest: 5.3.0
IPython: 7.7.0
sphinx: 2.1.2


</details>
","{""url"": ""https://api.github.com/repos/pydata/xarray/issues/4087/reactions"", ""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",,completed,13221727,issue
537934462,MDU6SXNzdWU1Mzc5MzQ0NjI=,3621,""".indexes"" not updated when setting values through "".values""",1277781,closed,0,,,1,2019-12-14T16:27:27Z,2019-12-16T18:38:10Z,2019-12-16T18:38:10Z,CONTRIBUTOR,,,,"#### MCVE Code Sample

```python
import xarray as xr

da1 = xr.DataArray([1,2],dims=['x'],coords={'x':[0,1]})

print(da1.indexes)
da1['x'].values = [1,2]
print(da1.indexes)
print('--------')
print(da1['x'])

>>> x: Int64Index([0, 1], dtype='int64', name='x')
    x: Int64Index([0, 1], dtype='int64', name='x')
    --------
    <xarray.DataArray 'x' (x: 2)>
    array([1, 2])
    Coordinates:
      * x        (x) int32 1 2
```

#### Expected Output

```python
x: Int64Index([0, 1], dtype='int64', name='x')
x: Int64Index([1, 2], dtype='int64', name='x')
--------
<xarray.DataArray 'x' (x: 2)>
array([1, 2])
Coordinates:
  * x        (x) int32 1 2
```
#### Problem Description
 * .indexes gets out of sync with the values stored in the array
 * this is unfortunate as alignment with other array is done through .indexes

The issue does not occur if I
  a, either do not call "".indexes"" before setting the value, or
  b, call `da1['x'] = [1,2]` instead of `da1['x'].values = [1,2]`


#### Output of ``xr.show_versions()``
<details>
INSTALLED VERSIONS
------------------
commit: None
python: 3.7.3 | packaged by conda-forge | (default, Jul  1 2019, 22:01:29) [MSC v.1900 64 bit (AMD64)]
python-bits: 64
OS: Windows
OS-release: 10
machine: AMD64
processor: Intel64 Family 6 Model 60 Stepping 3, GenuineIntel
byteorder: little
LC_ALL: None
LANG: None
LOCALE: None.None
libhdf5: 1.10.5
libnetcdf: 4.6.3
xarray: 0.14.1
pandas: 0.25.1
numpy: 1.17.1
scipy: 1.3.1
netCDF4: 1.5.2
pydap: None
h5netcdf: None
h5py: 2.10.0
Nio: None
zarr: None
cftime: 1.0.3.4
nc_time_axis: None
PseudoNetCDF: None
rasterio: None
cfgrib: None
iris: None
bottleneck: None
dask: 2.4.0
distributed: 2.5.1
matplotlib: 3.1.1
cartopy: None
seaborn: 0.9.0
numbagg: None
setuptools: 41.2.0
pip: 19.2.3
conda: None
pytest: 5.1.2
IPython: 7.8.0
sphinx: 2.2.0
</details>
","{""url"": ""https://api.github.com/repos/pydata/xarray/issues/3621/reactions"", ""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",,completed,13221727,issue
414277715,MDU6SXNzdWU0MTQyNzc3MTU=,2786,groupby with non-scalar coordinate,1277781,closed,0,,,1,2019-02-25T19:52:29Z,2019-10-11T15:55:36Z,2019-10-11T15:55:36Z,CONTRIBUTOR,,,,"#### Code Sample


```python
import numpy as np
import xarray as xr

def noop(da):
    return da

def expd(da):
    return da.expand_dims(['A'])

na=np.array([[1,2],[3,4]])
xa=xr.DataArray(na,dims=['A','B'])

# This works:
r1 = xa.groupby('A').apply(noop)
print(""!!!!"")

# This doesn't:
r2 = xa.groupby('A').apply(expd)
```
#### Problem description

Is this intended behavior? The reason I would need this is to be able to increase the size of each group.

#### Expected Output

I expect r1 to be equivalent to r2


","{""url"": ""https://api.github.com/repos/pydata/xarray/issues/2786/reactions"", ""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",,completed,13221727,issue
424115176,MDExOlB1bGxSZXF1ZXN0MjYzNTM4NTE4,2839,Fixing deepcopy for Dataset.attrs,1277781,closed,0,,,1,2019-03-22T09:24:54Z,2019-03-30T03:14:38Z,2019-03-30T03:14:38Z,CONTRIBUTOR,,0,pydata/xarray/pulls/2839,"<!-- Feel free to remove check-list items aren't relevant to your change -->

 - [x] Closes #2835
 - [X] Tests added
 - [X] Fully documented, including `whats-new.rst` for all changes and `api.rst` for new API
","{""url"": ""https://api.github.com/repos/pydata/xarray/issues/2839/reactions"", ""total_count"": 1, ""+1"": 1, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",,,13221727,pull
256251595,MDU6SXNzdWUyNTYyNTE1OTU=,1563,0.8.2 incompatible with pandas 0.20.1 ?,1277781,closed,0,,,4,2017-09-08T13:19:25Z,2017-09-08T23:15:36Z,2017-09-08T20:27:06Z,CONTRIBUTOR,,,,"This issue may be related to #1386   

I hope this part of the stacktrace is sufficient to demonstrate my point:

File ""C:\src\validation\main\risk_reporting\data_access\db_model.py"", line 246, in get_data
    ds = ds.groupby('pvshort').apply(select_latest_pv)
  File ""C:\Anaconda2\lib\site-packages\xarray\core\common.py"", line 345, in groupby
    return self.groupby_cls(self, group, squeeze=squeeze)
  File ""C:\Anaconda2\lib\site-packages\xarray\core\groupby.py"", line 226, in __init__
    unique_values, group_indices = unique_value_groups(group, sort=sort)
  File ""C:\Anaconda2\lib\site-packages\xarray\core\groupby.py"", line 34, in unique_value_groups
    inverse, values = pd.factorize(ar, sort=sort)
  File ""C:\Anaconda2\lib\site-packages\pandas\core\algorithms.py"", line 552, in factorize
    values = _ensure_arraylike(values)
  File ""C:\Anaconda2\lib\site-packages\pandas\core\algorithms.py"", line 166, in _ensure_arraylike
    values = lib.list_to_object_array(values)
TypeError: Argument 'obj' has incorrect type (expected list, got DataArray)

","{""url"": ""https://api.github.com/repos/pydata/xarray/issues/1563/reactions"", ""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",,completed,13221727,issue