Skip to content

Commit 123a555

Browse files
committed
Merge branch 'merge_constructor' of https://github.com/jwass/pandas into jwass-merge_constructor
Conflicts: doc/source/v0.15.0.txt
2 parents 7d3a0fa + 8ca9c85 commit 123a555

File tree

5 files changed

+36
-2
lines changed

5 files changed

+36
-2
lines changed

doc/source/merging.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,10 @@ Here's a description of what each argument is for:
376376
can be avoided are somewhat pathological but this option is provided
377377
nonetheless.
378378

379+
The return type will be the same as ``left``. If ``left`` is a ``DataFrame``
380+
and ``right`` is a subclass of DataFrame, the return type will still be
381+
``DataFrame``.
382+
379383
``merge`` is a function in the pandas namespace, and it is also available as a
380384
DataFrame instance method, with the calling DataFrame being implicitly
381385
considered the left object in the join.

doc/source/v0.15.0.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,8 @@ previously results in ``Exception`` or ``TypeError`` (:issue:`7812`)
167167
for localizing a specific level of a MultiIndex (:issue:`7846`)
168168

169169
- ``Timestamp.__repr__`` displays ``dateutil.tz.tzoffset`` info (:issue:`7907`)
170+
- ``merge``, ``DataFrame.merge``, and ``ordered_merge`` now return the same type
171+
as the ``left`` argument. (:issue:`7737`)
170172

171173
.. _whatsnew_0150.dt:
172174

pandas/core/frame.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@
135135
Returns
136136
-------
137137
merged : DataFrame
138+
The output type will the be same as 'left', if it is a subclass
139+
of DataFrame.
138140
"""
139141

140142
#----------------------------------------------------------------------

pandas/tools/merge.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ def ordered_merge(left, right, on=None, left_by=None, right_by=None,
106106
Returns
107107
-------
108108
merged : DataFrame
109+
The output type will the be same as 'left', if it is a subclass
110+
of DataFrame.
109111
"""
110112
def _merger(x, y):
111113
op = _OrderedMerge(x, y, on=on, left_on=left_on, right_on=right_on,
@@ -198,7 +200,8 @@ def get_result(self):
198200
axes=[llabels.append(rlabels), join_index],
199201
concat_axis=0, copy=self.copy)
200202

201-
result = DataFrame(result_data).__finalize__(self, method='merge')
203+
typ = self.left._constructor
204+
result = typ(result_data).__finalize__(self, method='merge')
202205

203206
self._maybe_add_join_keys(result, left_indexer, right_indexer)
204207

@@ -520,7 +523,8 @@ def get_result(self):
520523
axes=[llabels.append(rlabels), join_index],
521524
concat_axis=0, copy=self.copy)
522525

523-
result = DataFrame(result_data)
526+
typ = self.left._constructor
527+
result = typ(result_data).__finalize__(self, method='ordered_merge')
524528

525529
self._maybe_add_join_keys(result, left_indexer, right_indexer)
526530

pandas/tools/tests/test_merge.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,16 @@ def test_merge_nan_right(self):
781781
1: nan}})[['i1', 'i2', 'i1_', 'i3']]
782782
assert_frame_equal(result, expected)
783783

784+
def test_merge_type(self):
785+
class NotADataFrame(DataFrame):
786+
@property
787+
def _constructor(self):
788+
return NotADataFrame
789+
790+
nad = NotADataFrame(self.df)
791+
result = nad.merge(self.df2, on='key1')
792+
793+
tm.assert_isinstance(result, NotADataFrame)
784794

785795
def test_append_dtype_coerce(self):
786796

@@ -2154,6 +2164,18 @@ def test_multigroup(self):
21542164
result = ordered_merge(left, self.right, on='key', left_by='group')
21552165
self.assertTrue(result['group'].notnull().all())
21562166

2167+
def test_merge_type(self):
2168+
class NotADataFrame(DataFrame):
2169+
@property
2170+
def _constructor(self):
2171+
return NotADataFrame
2172+
2173+
nad = NotADataFrame(self.left)
2174+
result = nad.merge(self.right, on='key')
2175+
2176+
tm.assert_isinstance(result, NotADataFrame)
2177+
2178+
21572179
if __name__ == '__main__':
21582180
nose.runmodule(argv=[__file__, '-vvs', '-x', '--pdb', '--pdb-failure'],
21592181
exit=False)

0 commit comments

Comments
 (0)