Skip to content

Commit 9cb2c2d

Browse files
funnycrabjreback
authored andcommitted
BUG: Fix MultiIndex names handling in pd.concat
closes #15787 Author: Tong Shen <[email protected]> Closes #15955 from funnycrab/fix_bug_in_concat and squashes the following commits: 8c0e721 [Tong Shen] explicitly specify dtype when constructing DataFrame to avoid test failure db7866f [Tong Shen] construct expected results as DataFrame instead of FrozenList 7f82be9 [Tong Shen] BUG: Fix MultiIndex names handling in pd.concat
1 parent b4701a6 commit 9cb2c2d

File tree

3 files changed

+26
-1
lines changed

3 files changed

+26
-1
lines changed

doc/source/whatsnew/v0.20.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1241,6 +1241,7 @@ Indexing
12411241
- Bug in creating a ``MultiIndex`` with tuples and not passing a list of names; this will now raise ``ValueError`` (:issue:`15110`)
12421242
- Bug in the HTML display with with a ``MultiIndex`` and truncation (:issue:`14882`)
12431243
- Bug in the display of ``.info()`` where a qualifier (+) would always be displayed with a ``MultiIndex`` that contains only non-strings (:issue:`15245`)
1244+
- Bug in ``pd.concat()`` where the names of ``MultiIndex`` of resulting ``DataFrame`` are not handled correctly when ``None`` is presented in the names of ``MultiIndex`` of input ``DataFrame`` (:issue:`15787`)
12441245

12451246
I/O
12461247
^^^

pandas/indexes/api.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ def _get_consensus_names(indexes):
107107
# find the non-none names, need to tupleify to make
108108
# the set hashable, then reverse on return
109109
consensus_names = set([tuple(i.names) for i in indexes
110-
if all(n is not None for n in i.names)])
110+
if any(n is not None for n in i.names)])
111111
if len(consensus_names) == 1:
112112
return list(list(consensus_names)[0])
113113
return [None] * indexes[0].nlevels

pandas/tests/tools/test_concat.py

+24
Original file line numberDiff line numberDiff line change
@@ -1048,6 +1048,30 @@ def test_concat_multiindex_with_tz(self):
10481048
result = concat([df, df])
10491049
tm.assert_frame_equal(result, expected)
10501050

1051+
def test_concat_multiindex_with_none_in_index_names(self):
1052+
# GH 15787
1053+
index = pd.MultiIndex.from_product([[1], range(5)],
1054+
names=['level1', None])
1055+
df = pd.DataFrame({'col': range(5)}, index=index, dtype=np.int32)
1056+
1057+
result = concat([df, df], keys=[1, 2], names=['level2'])
1058+
index = pd.MultiIndex.from_product([[1, 2], [1], range(5)],
1059+
names=['level2', 'level1', None])
1060+
expected = pd.DataFrame({'col': list(range(5)) * 2},
1061+
index=index, dtype=np.int32)
1062+
assert_frame_equal(result, expected)
1063+
1064+
result = concat([df, df[:2]], keys=[1, 2], names=['level2'])
1065+
level2 = [1] * 5 + [2] * 2
1066+
level1 = [1] * 7
1067+
no_name = list(range(5)) + list(range(2))
1068+
tuples = list(zip(level2, level1, no_name))
1069+
index = pd.MultiIndex.from_tuples(tuples,
1070+
names=['level2', 'level1', None])
1071+
expected = pd.DataFrame({'col': no_name}, index=index,
1072+
dtype=np.int32)
1073+
assert_frame_equal(result, expected)
1074+
10511075
def test_concat_keys_and_levels(self):
10521076
df = DataFrame(np.random.randn(1, 3))
10531077
df2 = DataFrame(np.random.randn(1, 4))

0 commit comments

Comments
 (0)