diff --git a/doc/source/whatsnew/v0.15.2.txt b/doc/source/whatsnew/v0.15.2.txt index fc560782816ff..9c585cebcbe18 100644 --- a/doc/source/whatsnew/v0.15.2.txt +++ b/doc/source/whatsnew/v0.15.2.txt @@ -101,6 +101,7 @@ Bug Fixes - ``slice`` string method now takes step into account (:issue:`8754`) - Bug in ``BlockManager`` where setting values with different type would break block integrity (:issue:`8850`) - Bug in ``DatetimeIndex`` when using ``time`` object as key (:issue:`8667`) +- Bug in ``merge`` where ``how='left'`` and ``sort=False`` would not preserve left frame order (:issue:`7331`) - Fix negative step support for label-based slices (:issue:`8753`) Old behavior: diff --git a/pandas/tools/merge.py b/pandas/tools/merge.py index 2f0920b6d4e98..e19c0de884c31 100644 --- a/pandas/tools/merge.py +++ b/pandas/tools/merge.py @@ -479,8 +479,10 @@ def _get_join_indexers(left_keys, right_keys, sort=False, how='inner'): left_group_key, right_group_key, max_groups = \ _factorize_keys(left_group_key, right_group_key, sort=sort) + # preserve left frame order if how == 'left' and sort == False + kwargs = {'sort':sort} if how == 'left' else {} join_func = _join_functions[how] - return join_func(left_group_key, right_group_key, max_groups) + return join_func(left_group_key, right_group_key, max_groups, **kwargs) class _OrderedMerge(_MergeOperation): diff --git a/pandas/tools/tests/test_merge.py b/pandas/tools/tests/test_merge.py index c942998d430f4..96e4b32d2ad25 100644 --- a/pandas/tools/tests/test_merge.py +++ b/pandas/tools/tests/test_merge.py @@ -1022,6 +1022,13 @@ def test_left_join_index_multi_match_multiindex(self): tm.assert_frame_equal(result, expected) + # GH7331 - maintain left frame order in left merge + right.reset_index(inplace=True) + right.columns = left.columns[:3].tolist() + right.columns[-1:].tolist() + result = merge(left, right, how='left', on=left.columns[:-1].tolist()) + expected.index = np.arange(len(expected)) + tm.assert_frame_equal(result, expected) + def test_left_join_index_multi_match(self): left = DataFrame([ ['c', 0], @@ -1059,6 +1066,11 @@ def test_left_join_index_multi_match(self): tm.assert_frame_equal(result, expected) + # GH7331 - maintain left frame order in left merge + result = merge(left, right.reset_index(), how='left', on='tag') + expected.index = np.arange(len(expected)) + tm.assert_frame_equal(result, expected) + def test_join_multi_dtypes(self): # test with multi dtypes in the join index