Skip to content

BUG: Fix concat key name #14292

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 15 commits into from
Closed
1 change: 1 addition & 0 deletions doc/source/whatsnew/v0.19.1.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,4 @@ Performance Improvements

Bug Fixes
~~~~~~~~~
- Bug in ``concat`` where names of keys were not propagated to the resulting MultiIndex (:issue:`14252`)
39 changes: 31 additions & 8 deletions pandas/tests/frame/test_combine_concat.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,21 @@

from datetime import datetime

from numpy import nan
import numpy as np
from numpy import nan

from pandas.compat import lrange
from pandas import DataFrame, Series, Index, Timestamp
import pandas as pd

from pandas.util.testing import (assert_series_equal,
assert_frame_equal,
assertRaisesRegexp)

import pandas.util.testing as tm
from pandas import DataFrame, Index, Series, Timestamp
from pandas.compat import lrange

from pandas.tests.frame.common import TestData

import pandas.util.testing as tm
from pandas.util.testing import (assertRaisesRegexp,
assert_frame_equal,
assert_series_equal)


class TestDataFrameConcatCommon(tm.TestCase, TestData):

Expand Down Expand Up @@ -324,6 +324,29 @@ def test_join_multiindex_leftright(self):
assert_frame_equal(df2.join(df1, how='left'),
exp[['value2', 'value1']])

def test_concat_named_keys(self):
# GH 14252
df = pd.DataFrame({'foo': [1, 2], 'bar': [0.1, 0.2]})
index = Index(['a', 'b'], name='baz')
concatted_named_from_keys = pd.concat([df, df], keys=index)
expected_named = pd.DataFrame(
{'foo': [1, 2, 1, 2], 'bar': [0.1, 0.2, 0.1, 0.2]},
index=pd.MultiIndex.from_product((['a', 'b'], [0, 1]),
names=['baz', None]))
assert_frame_equal(concatted_named_from_keys, expected_named)

index_no_name = Index(['a', 'b'], name=None)
concatted_named_from_names = pd.concat(
[df, df], keys=index_no_name, names=['baz'])
assert_frame_equal(concatted_named_from_names, expected_named)

concatted_unnamed = pd.concat([df, df], keys=index_no_name)
expected_unnamed = pd.DataFrame(
{'foo': [1, 2, 1, 2], 'bar': [0.1, 0.2, 0.1, 0.2]},
index=pd.MultiIndex.from_product((['a', 'b'], [0, 1]),
names=[None, None]))
assert_frame_equal(concatted_unnamed, expected_unnamed)


class TestDataFrameCombineFirst(tm.TestCase, TestData):

Expand Down
6 changes: 4 additions & 2 deletions pandas/tools/merge.py
Original file line number Diff line number Diff line change
Expand Up @@ -1369,7 +1369,9 @@ 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
name = getattr(keys, 'name', None)
keys = _ensure_index(Index(clean_keys))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm I don't think you need the _ensure_index if you are forcing the index

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes appears that is correct: cdc76f6 looks fine.

keys.name = name

if len(objs) == 0:
raise ValueError('All objects passed were None')
Expand Down Expand Up @@ -1454,7 +1456,7 @@ def __init__(self, objs, axis=0, join='outer', join_axes=None,
self.axis = axis
self.join_axes = join_axes
self.keys = keys
self.names = names
self.names = names or getattr(keys, 'names', None)
self.levels = levels

self.ignore_index = ignore_index
Expand Down