Skip to content

Commit 6532ab2

Browse files
committed
ERR automatic broadcast for merging different levels, #9455
closes #9455 closes #12219
1 parent ed3d145 commit 6532ab2

File tree

4 files changed

+39
-3
lines changed

4 files changed

+39
-3
lines changed

doc/source/whatsnew/v0.18.1.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ API changes
4747

4848

4949

50-
50+
- ``pandas.merge()`` and ``DataFrame.join()`` will show a ``UserWarning`` when merging/joining a single- with a multi-leveled dataframe (:issue:`9455`, :issue:`12219`)
5151

5252

5353

pandas/tests/frame/test_axis_select_reindex.py

+25
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,31 @@ def test_drop_multiindex_not_lexsorted(self):
142142

143143
tm.assert_frame_equal(result, expected)
144144

145+
def test_merge_join_different_levels(self):
146+
# GH 9455
147+
148+
# first dataframe
149+
df1 = DataFrame(columns=['a', 'b'], data=[[1, 11], [0, 22]])
150+
151+
# second dataframe
152+
columns = MultiIndex.from_tuples([('a', ''), ('c', 'c1')])
153+
df2 = DataFrame(columns=columns, data=[[1, 33], [0, 44]])
154+
155+
# merge
156+
columns = ['a', 'b', ('c', 'c1')]
157+
expected = DataFrame(columns=columns, data=[[1, 11, 33], [0, 22, 44]])
158+
with tm.assert_produces_warning(UserWarning):
159+
result = pd.merge(df1, df2, on='a')
160+
tm.assert_frame_equal(result, expected)
161+
162+
# join, see discussion in GH 12219
163+
columns = ['a', 'b', ('a', ''), ('c', 'c1')]
164+
expected = DataFrame(columns=columns,
165+
data=[[1, 11, 0, 44], [0, 22, 1, 33]])
166+
with tm.assert_produces_warning(UserWarning):
167+
result = df1.join(df2, on='a')
168+
tm.assert_frame_equal(result, expected)
169+
145170
def test_reindex(self):
146171
newFrame = self.frame.reindex(self.ts1.index)
147172

pandas/tools/merge.py

+9
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
SQL-style merge routines
33
"""
44

5+
import warnings
6+
57
import numpy as np
68
from pandas.compat import range, lrange, lzip, zip, map, filter
79
import pandas.compat as compat
@@ -193,6 +195,13 @@ def __init__(self, left, right, how='inner', on=None,
193195
'can not merge DataFrame with instance of '
194196
'type {0}'.format(type(right)))
195197

198+
# warn user when merging between different levels
199+
if left.columns.nlevels != right.columns.nlevels:
200+
msg = ('merging between different levels can give an unintended '
201+
'result ({0} levels on the left, {1} on the right)')
202+
msg = msg.format(left.columns.nlevels, right.columns.nlevels)
203+
warnings.warn(msg, UserWarning)
204+
196205
# note this function has side effects
197206
(self.left_join_keys,
198207
self.right_join_keys,

pandas/tools/tests/test_merge.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -459,13 +459,15 @@ def test_join_inner_multiindex(self):
459459
# _assert_same_contents(expected, expected2.ix[:, expected.columns])
460460

461461
def test_join_hierarchical_mixed(self):
462+
# GH 2024
462463
df = DataFrame([(1, 2, 3), (4, 5, 6)], columns=['a', 'b', 'c'])
463464
new_df = df.groupby(['a']).agg({'b': [np.mean, np.sum]})
464465
other_df = DataFrame(
465466
[(1, 2, 3), (7, 10, 6)], columns=['a', 'b', 'd'])
466467
other_df.set_index('a', inplace=True)
467-
468-
result = merge(new_df, other_df, left_index=True, right_index=True)
468+
# GH 9455, 12219
469+
with tm.assert_produces_warning(UserWarning):
470+
result = merge(new_df, other_df, left_index=True, right_index=True)
469471
self.assertTrue(('b', 'mean') in result)
470472
self.assertTrue('b' in result)
471473

0 commit comments

Comments
 (0)