@@ -384,17 +384,16 @@ def shift(self, indexer, periods):
384
384
new_values [:, periods :] = np .nan
385
385
return make_block (new_values , self .items , self .ref_items )
386
386
387
- def where (self , func , other , cond = None , raise_on_error = True , try_cast = False ):
387
+ def eval (self , func , other , raise_on_error = True , try_cast = False ):
388
388
"""
389
- evaluate the block; return result block(s) from the result
389
+ evaluate the block; return result block from the result
390
390
391
391
Parameters
392
392
----------
393
393
func : how to combine self, other
394
394
other : a ndarray/object
395
- cond : the condition to respect, optional
396
- raise_on_error : if True, raise when I can't perform the function,
397
- False by default (and just return the data that we had coming in)
395
+ raise_on_error : if True, raise when I can't perform the function, False by default (and just return
396
+ the data that we had coming in)
398
397
399
398
Returns
400
399
-------
@@ -414,28 +413,7 @@ def where(self, func, other, cond = None, raise_on_error = True, try_cast = Fals
414
413
values = values .T
415
414
is_transposed = True
416
415
417
- # see if we can align cond
418
- if cond is not None :
419
- if not hasattr (cond , 'shape' ):
420
- raise ValueError ('where must have a condition that is ndarray'
421
- ' like' )
422
- if hasattr (cond , 'reindex_axis' ):
423
- axis = getattr (cond , '_het_axis' , 0 )
424
- cond = cond .reindex_axis (self .items , axis = axis ,
425
- copy = True ).values
426
- else :
427
- cond = cond .values
428
-
429
- # may need to undo transpose of values
430
- if hasattr (values , 'ndim' ):
431
- if (values .ndim != cond .ndim or
432
- values .shape == cond .shape [::- 1 ]):
433
- values = values .T
434
- is_transposed = not is_transposed
435
-
436
416
args = [ values , other ]
437
- if cond is not None :
438
- args .append (cond )
439
417
try :
440
418
result = func (* args )
441
419
except :
@@ -458,7 +436,105 @@ def where(self, func, other, cond = None, raise_on_error = True, try_cast = Fals
458
436
if try_cast :
459
437
result = self ._try_cast_result (result )
460
438
461
- return [ make_block (result , self .items , self .ref_items ) ]
439
+ return make_block (result , self .items , self .ref_items )
440
+
441
+ def where (self , other , cond , raise_on_error = True , try_cast = False ):
442
+ """
443
+ evaluate the block; return result block(s) from the result
444
+
445
+ Parameters
446
+ ----------
447
+ other : a ndarray/object
448
+ cond : the condition to respect
449
+ raise_on_error : if True, raise when I can't perform the function, False by default (and just return
450
+ the data that we had coming in)
451
+
452
+ Returns
453
+ -------
454
+ a new block(s), the result of the func
455
+ """
456
+
457
+ values = self .values
458
+
459
+ # see if we can align other
460
+ if hasattr (other ,'reindex_axis' ):
461
+ axis = getattr (other ,'_het_axis' ,0 )
462
+ other = other .reindex_axis (self .items , axis = axis , copy = True ).values
463
+
464
+ # make sure that we can broadcast
465
+ is_transposed = False
466
+ if hasattr (other , 'ndim' ) and hasattr (values , 'ndim' ):
467
+ if values .ndim != other .ndim or values .shape == other .shape [::- 1 ]:
468
+ values = values .T
469
+ is_transposed = True
470
+
471
+ # see if we can align cond
472
+ if not hasattr (cond ,'shape' ):
473
+ raise ValueError ("where must have a condition that is ndarray like" )
474
+ if hasattr (cond ,'reindex_axis' ):
475
+ axis = getattr (cond ,'_het_axis' ,0 )
476
+ cond = cond .reindex_axis (self .items , axis = axis , copy = True ).values
477
+ else :
478
+ cond = cond .values
479
+
480
+ # may need to undo transpose of values
481
+ if hasattr (values , 'ndim' ):
482
+ if values .ndim != cond .ndim or values .shape == cond .shape [::- 1 ]:
483
+ values = values .T
484
+ is_transposed = not is_transposed
485
+
486
+ # our where function
487
+ def func (c ,v ,o ):
488
+ if c .flatten ().all ():
489
+ return v
490
+
491
+ try :
492
+ return np .where (c ,v ,o )
493
+ except :
494
+ if raise_on_error :
495
+ raise TypeError ('Coulnd not operate %s with block values'
496
+ % repr (o ))
497
+ else :
498
+ # return the values
499
+ result = np .empty (v .shape ,dtype = 'O' )
500
+ result .fill (np .nan )
501
+ return result
502
+
503
+ def create_block (result , items , transpose = True ):
504
+ if not isinstance (result , np .ndarray ):
505
+ raise TypeError ('Could not compare %s with block values'
506
+ % repr (other ))
507
+
508
+ if transpose and is_transposed :
509
+ result = result .T
510
+
511
+ # try to cast if requested
512
+ if try_cast :
513
+ result = self ._try_cast_result (result )
514
+
515
+ return make_block (result , items , self .ref_items )
516
+
517
+ # see if we can operate on the entire block, or need item-by-item
518
+ if cond .all ().any ():
519
+ result_blocks = []
520
+ for item in self .items :
521
+ loc = self .items .get_loc (item )
522
+ item = self .items .take ([loc ])
523
+ v = values .take ([loc ])
524
+ c = cond .take ([loc ])
525
+ o = other .take ([loc ]) if hasattr (other ,'shape' ) else other
526
+
527
+ result = func (c ,v ,o )
528
+ if len (result ) == 1 :
529
+ result = np .repeat (result ,self .shape [1 :])
530
+
531
+ result = result .reshape (((1 ,) + self .shape [1 :]))
532
+ result_blocks .append (create_block (result , item , transpose = False ))
533
+
534
+ return result_blocks
535
+ else :
536
+ result = func (cond ,values ,other )
537
+ return create_block (result , self .items )
462
538
463
539
def _mask_missing (array , missing_values ):
464
540
if not isinstance (missing_values , (list , np .ndarray )):
@@ -840,6 +916,9 @@ def apply(self, f, *args, **kwargs):
840
916
def where (self , * args , ** kwargs ):
841
917
return self .apply ('where' , * args , ** kwargs )
842
918
919
+ def eval (self , * args , ** kwargs ):
920
+ return self .apply ('eval' , * args , ** kwargs )
921
+
843
922
def putmask (self , * args , ** kwargs ):
844
923
return self .apply ('putmask' , * args , ** kwargs )
845
924
0 commit comments