Repository: pandas-dev/pandas
Pull request: BUG: copying series into empty dataframe does not preserve dataframe index name
- [x] closes #31368
- [x] tests added / passed
   `indexing/test_partial.py:TestPartialSetting:test_index_name_empty`
- [x] passes `black pandas`
- [x] passes `git diff upstream/master -u -- "*.py" | flake8 --diff`
- [x] whatsnew entry


Problem statement:
Index name assignment resolution logic changes depending on whether DataFrame has any rows
#### Code Sample, a copy-pastable example if possible

```python
import pandas as pd

def get_name_of_assigned_index(df_size, series_size):
  df = pd.DataFrame({}, index=pd.RangeIndex(df_size, name='df_index'))
  series = pd.Series(1.23, index=pd.RangeIndex(series_size, name='series_index'))

  df['series'] = series

  return df.index.name
```
#### Problem description

`get_name_of_assigned_index(n, m)` returns `'df_index'` *unless* `n = 0`, in which case it returns `'series_index'`.

I don't know which of these is necessarily the better behavior, but the resulting index name ought to be consistent regardless of how many - or few - rows are in the DataFrame. Subsequent operations may rely on expectations about that name, so this behavior, wherein the name changes as an unintuitive consequence of a rowless frame, could cause bugs.

#### Output of ``pd.show_versions()``

<details>

INSTALLED VERSIONS
------------------
commit: None
python: 3.6.7.final.0
python-bits: 64
OS: Linux
OS-release: 4.3.5-smp-821.23.0.0
machine: x86_64
processor: 
byteorder: little
LC_ALL: en_US.UTF-8
LANG: None
LOCALE: en_US.UTF-8

pandas: 0.24.2
pytest: None
pip: None
setuptools: unknown
Cython: None
numpy: 1.16.4
scipy: 1.2.1
pyarrow: None
xarray: None
IPython: 2.0.0
sphinx: None
patsy: 0.4.1
dateutil: 2.8.1
pytz: 2019.3
blosc: None
bottleneck: None
tables: 3.5.2
numexpr: 2.6.10dev0
feather: None
matplotlib: 3.0.3
openpyxl: None
xlrd: 1.2.0
xlwt: None
xlsxwriter: None
lxml.etree: None
bs4: None
html5lib: 1.0.1
sqlalchemy: None
pymysql: None
psycopg2: None
jinja2: 2.10.3
s3fs: None
fastparquet: None
pandas_gbq: 0+unknown
pandas_datareader: None
gcsfs: None

</details>

Hints from issue discussion:
Thanks for the report - could you please make sure your snippet is [self-contained](https://pandas.pydata.org/pandas-docs/stable/development/contributing.html#bug-reports-and-enhancement-requests)?

Currently, it's not runnable (missing brackets at the end of the DataFrame and Series constructors, undefined variables `n` and `m` in the function `get_name_of_assigned_index`)
Sorry; should be correct now.

Commit message: add whatsnew

Patch to review:
diff --git a/doc/source/whatsnew/v1.1.2.rst b/doc/source/whatsnew/v1.1.2.rst
index d1a66256454ca..2343ab2cb2c61 100644
--- a/doc/source/whatsnew/v1.1.2.rst
+++ b/doc/source/whatsnew/v1.1.2.rst
@@ -36,6 +36,7 @@ Bug fixes
 - Bug in :meth:`Float64Index.__contains__` incorrectly raising ``TypeError`` instead of returning ``False`` (:issue:`35788`)
 - Bug in :meth:`Series.dt.isocalendar` and :meth:`DatetimeIndex.isocalendar` that returned incorrect year for certain dates (:issue:`36032`)
 - Bug in :class:`DataFrame` indexing returning an incorrect :class:`Series` in some cases when the series has been altered and a cache not invalidated (:issue:`33675`)
+- Bug when setting empty :class:`DataFrame` column to a :class:`Series` in preserving name of index in frame (:issue:`31368`)
 
 .. ---------------------------------------------------------------------------
 
diff --git a/pandas/core/frame.py b/pandas/core/frame.py
index c48bec9b670ad..95aed996dddd9 100644
--- a/pandas/core/frame.py
+++ b/pandas/core/frame.py
@@ -3206,9 +3206,11 @@ def _ensure_valid_index(self, value):
                     "and a value that cannot be converted to a Series"
                 ) from err
 
-            self._mgr = self._mgr.reindex_axis(
-                value.index.copy(), axis=1, fill_value=np.nan
-            )
+            # GH31368 preserve name of index
+            index_copy = value.index.copy()
+            index_copy.name = self.index.name
+
+            self._mgr = self._mgr.reindex_axis(index_copy, axis=1, fill_value=np.nan)
 
     def _box_col_values(self, values, loc: int) -> Series:
         """
diff --git a/pandas/tests/indexing/test_partial.py b/pandas/tests/indexing/test_partial.py
index 350f86b4e9fd0..12d759b8937ec 100644
--- a/pandas/tests/indexing/test_partial.py
+++ b/pandas/tests/indexing/test_partial.py
@@ -660,3 +660,12 @@ def test_indexing_timeseries_regression(self):
         expected = Series(rng, index=rng)
 
         tm.assert_series_equal(result, expected)
+
+    def test_index_name_empty(self):
+        # GH 31368
+        df = pd.DataFrame({}, index=pd.RangeIndex(0, name="df_index"))
+        series = pd.Series(1.23, index=pd.RangeIndex(4, name="series_index"))
+
+        df["series"] = series
+
+        tm.assert_equal(df.index.name, "df_index")


Code review comments:
diff_hunk: @@ -660,3 +660,12 @@ def test_indexing_timeseries_regression(self):
         expected = Series(rng, index=rng)
 
         tm.assert_series_equal(result, expected)
+
+    def test_index_name_empty(self):
+        # GH 31368
+        df = pd.DataFrame({}, index=pd.RangeIndex(0, name="df_index"))
+        series = pd.Series(1.23, index=pd.RangeIndex(4, name="series_index"))
+
+        df["series"] = series
+
+        tm.assert_equal(df.index.name, "df_index")
path: pandas/tests/indexing/test_partial.py
text: @user1:
can you construct the expected frame and use tm.assert_frame_equal