@@ -5253,7 +5253,6 @@ def reorder_levels(self, order, axis=0):
5253
5253
5254
5254
def _combine_frame (self , other , func , fill_value = None , level = None ):
5255
5255
this , other = self .align (other , join = "outer" , level = level , copy = False )
5256
- new_index , new_columns = this .index , this .columns
5257
5256
5258
5257
if fill_value is None :
5259
5258
# since _arith_op may be called in a loop, avoid function call
@@ -5271,38 +5270,62 @@ def _arith_op(left, right):
5271
5270
5272
5271
if ops .should_series_dispatch (this , other , func ):
5273
5272
# iterate over columns
5274
- return ops .dispatch_to_series (this , other , _arith_op )
5273
+ new_data = ops .dispatch_to_series (this , other , _arith_op )
5275
5274
else :
5276
5275
with np .errstate (all = "ignore" ):
5277
- result = _arith_op (this .values , other .values )
5278
- result = dispatch_fill_zeros (func , this .values , other .values , result )
5279
- return self ._constructor (
5280
- result , index = new_index , columns = new_columns , copy = False
5281
- )
5276
+ res_values = _arith_op (this .values , other .values )
5277
+ new_data = dispatch_fill_zeros (func , this .values , other .values , res_values )
5278
+ return this ._construct_result (other , new_data , _arith_op )
5282
5279
5283
5280
def _combine_match_index (self , other , func , level = None ):
5284
5281
left , right = self .align (other , join = "outer" , axis = 0 , level = level , copy = False )
5285
5282
# at this point we have `left.index.equals(right.index)`
5286
5283
5287
5284
if left ._is_mixed_type or right ._is_mixed_type :
5288
5285
# operate column-wise; avoid costly object-casting in `.values`
5289
- return ops .dispatch_to_series (left , right , func )
5286
+ new_data = ops .dispatch_to_series (left , right , func )
5290
5287
else :
5291
5288
# fastpath --> operate directly on values
5292
5289
with np .errstate (all = "ignore" ):
5293
5290
new_data = func (left .values .T , right .values ).T
5294
- return self ._constructor (
5295
- new_data , index = left .index , columns = self .columns , copy = False
5296
- )
5291
+ return left ._construct_result (other , new_data , func )
5297
5292
5298
5293
def _combine_match_columns (self , other : Series , func , level = None ):
5299
5294
left , right = self .align (other , join = "outer" , axis = 1 , level = level , copy = False )
5300
5295
# at this point we have `left.columns.equals(right.index)`
5301
- return ops .dispatch_to_series (left , right , func , axis = "columns" )
5296
+ new_data = ops .dispatch_to_series (left , right , func , axis = "columns" )
5297
+ return left ._construct_result (right , new_data , func )
5302
5298
5303
5299
def _combine_const (self , other , func ):
5304
5300
# scalar other or np.ndim(other) == 0
5305
- return ops .dispatch_to_series (self , other , func )
5301
+ new_data = ops .dispatch_to_series (self , other , func )
5302
+ return self ._construct_result (other , new_data , func )
5303
+
5304
+ def _construct_result (self , other , result , func ):
5305
+ """
5306
+ Wrap the result of an arithmetic, comparison, or logical operation.
5307
+
5308
+ Parameters
5309
+ ----------
5310
+ other : object
5311
+ result : DataFrame
5312
+ func : binary operator
5313
+
5314
+ Returns
5315
+ -------
5316
+ DataFrame
5317
+
5318
+ Notes
5319
+ -----
5320
+ `func` is included for compat with SparseDataFrame signature, is not
5321
+ needed here.
5322
+ """
5323
+ out = self ._constructor (result , index = self .index , copy = False )
5324
+ # Pin columns instead of passing to constructor for compat with
5325
+ # non-unique columns case
5326
+ out .columns = self .columns
5327
+ return out
5328
+ # TODO: finalize? we do for SparseDataFrame
5306
5329
5307
5330
def combine (self , other , func , fill_value = None , overwrite = True ):
5308
5331
"""
@@ -6206,12 +6229,13 @@ def explode(self, column: Union[str, Tuple]) -> "DataFrame":
6206
6229
if not self .columns .is_unique :
6207
6230
raise ValueError ("columns must be unique" )
6208
6231
6209
- result = self [column ].explode ()
6210
- return (
6211
- self .drop ([column ], axis = 1 )
6212
- .join (result )
6213
- .reindex (columns = self .columns , copy = False )
6214
- )
6232
+ df = self .reset_index (drop = True )
6233
+ result = df [column ].explode ()
6234
+ result = df .drop ([column ], axis = 1 ).join (result )
6235
+ result .index = self .index .take (result .index )
6236
+ result = result .reindex (columns = self .columns , copy = False )
6237
+
6238
+ return result
6215
6239
6216
6240
def unstack (self , level = - 1 , fill_value = None ):
6217
6241
"""
0 commit comments