diff --git a/doc/source/whatsnew/v0.18.1.txt b/doc/source/whatsnew/v0.18.1.txt index 7d79367cef1e2..14b630476f8bd 100644 --- a/doc/source/whatsnew/v0.18.1.txt +++ b/doc/source/whatsnew/v0.18.1.txt @@ -225,6 +225,7 @@ Bug Fixes +- Bug in ``.str`` accessor methods may raise ``ValueError`` if input has ``name`` and the result is ``DataFrame`` or ``MultiIndex`` (:issue:`12617`) - Bug in ``CategoricalIndex.get_loc`` returns different result from regular ``Index`` (:issue:`12531`) diff --git a/pandas/core/strings.py b/pandas/core/strings.py index 81e1922db1b09..e5d539821e3ca 100644 --- a/pandas/core/strings.py +++ b/pandas/core/strings.py @@ -1329,12 +1329,15 @@ def cons_row(x): if not isinstance(expand, bool): raise ValueError("expand must be True or False") - if name is None: - name = getattr(result, 'name', None) - if name is None: - # do not use logical or, _orig may be a DataFrame - # which has "name" column - name = self._orig.name + if expand is False: + # if expand is False, result should have the same name + # as the original otherwise specified + if name is None: + name = getattr(result, 'name', None) + if name is None: + # do not use logical or, _orig may be a DataFrame + # which has "name" column + name = self._orig.name # Wait until we are sure result is a Series or Index before # checking attributes (GH 12180) diff --git a/pandas/tests/test_strings.py b/pandas/tests/test_strings.py index 6c16225878d22..d61ae3681a880 100644 --- a/pandas/tests/test_strings.py +++ b/pandas/tests/test_strings.py @@ -1938,6 +1938,30 @@ def test_rsplit_to_multiindex_expand(self): tm.assert_index_equal(result, exp) self.assertEqual(result.nlevels, 2) + def test_split_with_name(self): + # GH 12617 + + # should preserve name + s = Series(['a,b', 'c,d'], name='xxx') + res = s.str.split(',') + exp = Series([('a', 'b'), ('c', 'd')], name='xxx') + tm.assert_series_equal(res, exp) + + res = s.str.split(',', expand=True) + exp = DataFrame([['a', 'b'], ['c', 'd']]) + tm.assert_frame_equal(res, exp) + + idx = Index(['a,b', 'c,d'], name='xxx') + res = idx.str.split(',') + exp = Index([['a', 'b'], ['c', 'd']], name='xxx') + self.assertTrue(res.nlevels, 1) + tm.assert_index_equal(res, exp) + + res = idx.str.split(',', expand=True) + exp = MultiIndex.from_tuples([('a', 'b'), ('c', 'd')]) + self.assertTrue(res.nlevels, 2) + tm.assert_index_equal(res, exp) + def test_partition_series(self): values = Series(['a_b_c', 'c_d_e', NA, 'f_g_h']) @@ -2059,6 +2083,31 @@ def test_partition_to_dataframe(self): 2: ['c', 'e', np.nan, 'h']}) tm.assert_frame_equal(result, exp) + def test_partition_with_name(self): + # GH 12617 + + s = Series(['a,b', 'c,d'], name='xxx') + res = s.str.partition(',') + exp = DataFrame({0: ['a', 'c'], 1: [',', ','], 2: ['b', 'd']}) + tm.assert_frame_equal(res, exp) + + # should preserve name + res = s.str.partition(',', expand=False) + exp = Series([('a', ',', 'b'), ('c', ',', 'd')], name='xxx') + tm.assert_series_equal(res, exp) + + idx = Index(['a,b', 'c,d'], name='xxx') + res = idx.str.partition(',') + exp = MultiIndex.from_tuples([('a', ',', 'b'), ('c', ',', 'd')]) + self.assertTrue(res.nlevels, 3) + tm.assert_index_equal(res, exp) + + # should preserve name + res = idx.str.partition(',', expand=False) + exp = Index(np.array([('a', ',', 'b'), ('c', ',', 'd')]), name='xxx') + self.assertTrue(res.nlevels, 1) + tm.assert_index_equal(res, exp) + def test_pipe_failures(self): # #2119 s = Series(['A|B|C'])