diff --git a/doc/source/whatsnew/v0.18.0.txt b/doc/source/whatsnew/v0.18.0.txt index 5b8c282d3e4ed..ea5c3b6e4c7d0 100644 --- a/doc/source/whatsnew/v0.18.0.txt +++ b/doc/source/whatsnew/v0.18.0.txt @@ -238,4 +238,6 @@ Bug Fixes - Bug in ``df.replace`` while replacing value in mixed dtype ``Dataframe`` (:issue:`11698`) +- Bug in ``Index`` prevent copying name of passed ``Index`` or ``DatetimeIndex`` objects, when a new name is not provided (:issue:`11193`) + - Bug in ``read_excel`` failing to read any non-empty sheets when empty sheets exist and ``sheetname=None`` (:issue:`11711`) diff --git a/pandas/core/index.py b/pandas/core/index.py index 9b75153d9b84b..6da30ffefb41f 100644 --- a/pandas/core/index.py +++ b/pandas/core/index.py @@ -120,6 +120,9 @@ class Index(IndexOpsMixin, StringAccessorMixin, PandasObject): def __new__(cls, data=None, dtype=None, copy=False, name=None, fastpath=False, tupleize_cols=True, **kwargs): + if name is None and hasattr(data, 'name'): + name = data.name + # no class inference! if fastpath: return cls._simple_new(data, name) @@ -128,6 +131,7 @@ def __new__(cls, data=None, dtype=None, copy=False, name=None, fastpath=False, return CategoricalIndex(data, copy=copy, name=name, **kwargs) if isinstance(data, (np.ndarray, Index, ABCSeries)): + if issubclass(data.dtype.type, np.datetime64) or is_datetimetz(data): from pandas.tseries.index import DatetimeIndex result = DatetimeIndex(data, copy=copy, name=name, **kwargs) @@ -4052,6 +4056,8 @@ def __new__(cls, levels=None, labels=None, sortorder=None, names=None, # compat with Index if name is not None: names = name +# elif cls.names is not None: +# names = cls.names if levels is None or labels is None: raise TypeError("Must pass both levels and labels") if len(levels) != len(labels): diff --git a/pandas/tests/test_base.py b/pandas/tests/test_base.py index 5d959892791fe..db391dca7114c 100644 --- a/pandas/tests/test_base.py +++ b/pandas/tests/test_base.py @@ -415,6 +415,7 @@ def test_value_counts_unique_nunique(self): # resets name from Index expected_index = pd.Index(o[::-1]) + expected_index.name = None # attach name to klass o = o.repeat(range(1, len(o) + 1)) @@ -424,16 +425,18 @@ def test_value_counts_unique_nunique(self): # resets name from Index expected_index = pd.Index(o[::-1]) + expected_index.name = None # attach name to klass o = o.repeat(range(1, len(o) + 1)) o.name = 'a' # don't test boolean - elif isinstance(o,Index) and o.is_boolean(): + elif isinstance(o, Index) and o.is_boolean(): continue elif isinstance(o, Index): expected_index = pd.Index(values[::-1]) + expected_index.name = None o = o.repeat(range(1, len(o) + 1)) o.name = 'a' else: diff --git a/pandas/tests/test_index.py b/pandas/tests/test_index.py index e2fa6a90429dc..a240b8c1c1e78 100644 --- a/pandas/tests/test_index.py +++ b/pandas/tests/test_index.py @@ -60,6 +60,31 @@ def test_shift(self): self.assertRaises(NotImplementedError, idx.shift, 1) self.assertRaises(NotImplementedError, idx.shift, 1, 2) + def test_create_index_existing_name(self): + + # GH11193, when an existing index is passed, and a new name is not specified, the new index should inherit the + # previous object name + expected = self.create_index() + if not isinstance(expected, MultiIndex): + expected.name = 'foo' + result = pd.Index(expected) + tm.assert_index_equal(result, expected) + + result = pd.Index(expected, name='bar') + expected.name = 'bar' + tm.assert_index_equal(result, expected) + else: + expected.names = ['foo', 'bar'] + result = pd.Index(expected) + tm.assert_index_equal(result, Index(Index([('foo', 'one'), ('foo', 'two'), ('bar', 'one'), ('baz', 'two'), + ('qux', 'one'), ('qux', 'two')], dtype='object'), + names=['foo', 'bar'])) + + result = pd.Index(expected, names=['A', 'B']) + tm.assert_index_equal(result, Index(Index([('foo', 'one'), ('foo', 'two'), ('bar', 'one'), ('baz', 'two'), + ('qux', 'one'), ('qux', 'two')], dtype='object'), + names=['A', 'B'])) + def test_numeric_compat(self): idx = self.create_index() @@ -3043,7 +3068,7 @@ def test_identical(self): i = self.index.copy(dtype=object) i = i.rename('foo') same_values = Index(i, dtype=object) - self.assertTrue(same_values.identical(self.index.copy(dtype=object))) + self.assertTrue(same_values.identical(i)) self.assertFalse(i.identical(self.index)) self.assertTrue(Index(same_values, name='foo', dtype=object