diff --git a/doc/source/whatsnew/v0.19.0.txt b/doc/source/whatsnew/v0.19.0.txt index ffc6757b674ea..6dd2242372a04 100644 --- a/doc/source/whatsnew/v0.19.0.txt +++ b/doc/source/whatsnew/v0.19.0.txt @@ -1576,3 +1576,4 @@ Bug Fixes - Bugs in ``stack``, ``get_dummies``, ``make_axis_dummies`` which don't preserve categorical dtypes in (multi)indexes (:issue:`13854`) - ``PeridIndex`` can now accept ``list`` and ``array`` which contains ``pd.NaT`` (:issue:`13430`) - Bug in ``df.groupby`` where ``.median()`` returns arbitrary values if grouped dataframe contains empty bins (:issue:`13629`) +- Bug in ``pandas.concat`` does not preserve Index name (:issue:`14252`) diff --git a/pandas/indexes/multi.py b/pandas/indexes/multi.py index 09c755b2c9792..a6548710590fe 100644 --- a/pandas/indexes/multi.py +++ b/pandas/indexes/multi.py @@ -152,9 +152,10 @@ def _set_levels(self, levels, level=None, copy=False, validate=True, raise ValueError('Length of levels must match length of level.') if level is None: - new_levels = FrozenList( - _ensure_index(lev, copy=copy)._shallow_copy() - for lev in levels) + new_levels = [] + for lev in levels: + new_levels.append( + _ensure_index(lev, copy=copy)._shallow_copy()) else: level = [self._get_level_number(l) for l in level] new_levels = list(self._levels) diff --git a/pandas/tools/merge.py b/pandas/tools/merge.py index 6521acbd0b733..da0b8cdf77ef3 100644 --- a/pandas/tools/merge.py +++ b/pandas/tools/merge.py @@ -1369,7 +1369,7 @@ def __init__(self, objs, axis=0, join='outer', join_axes=None, clean_keys.append(k) clean_objs.append(v) objs = clean_objs - keys = clean_keys + keys = Index(clean_keys, name=keys.name) if len(objs) == 0: raise ValueError('All objects passed were None') @@ -1685,7 +1685,6 @@ def _make_concat_multiindex(indexes, keys, levels=None, names=None): # also copies names = names + _get_consensus_names(indexes) - return MultiIndex(levels=levels, labels=label_list, names=names, verify_integrity=False) @@ -1694,8 +1693,8 @@ def _make_concat_multiindex(indexes, keys, levels=None, names=None): kpieces = len(indexes) # also copies - new_names = list(names) - new_levels = list(levels) + new_names = names + new_levels = levels # construct labels new_labels = [] @@ -1723,8 +1722,12 @@ def _make_concat_multiindex(indexes, keys, levels=None, names=None): if len(new_names) < len(new_levels): new_names.extend(new_index.names) - return MultiIndex(levels=new_levels, labels=new_labels, names=new_names, - verify_integrity=False) + if any(new_names): + return MultiIndex(levels=new_levels, labels=new_labels, + names=new_names, verify_integrity=False) + else: + return MultiIndex(levels=new_levels, labels=new_labels, + verify_integrity=False) def _should_fill(lname, rname): diff --git a/pandas/tools/tests/test_merge.py b/pandas/tools/tests/test_merge.py index 6e36100ddd0b4..1675ffc54f8e9 100644 --- a/pandas/tools/tests/test_merge.py +++ b/pandas/tools/tests/test_merge.py @@ -11,6 +11,7 @@ import pandas as pd from pandas.compat import lrange, lzip from pandas.tools.merge import merge, concat, MergeError +from pandas.core.base import FrozenList from pandas.util.testing import (assert_frame_equal, assert_series_equal, slow) @@ -834,6 +835,14 @@ def test_merge_right_vs_left(self): merged2 = merged2.ix[:, merged1.columns] assert_frame_equal(merged1, merged2) + def test_concat_keys(self): + df = pd.DataFrame({'foo': [1, 2, 3, 4], + 'bar': [0.1, 0.2, 0.3, 0.4]}) + index = pd.Index(['a', 'b'], name='baz') + + concatted = pd.concat([df, df], keys=index) + self.assertEqual(FrozenList(['baz', None]), concatted.index.names) + def test_compress_group_combinations(self): # ~ 40000000 possible unique groups