31
31
_is_index_slice , _check_bool_indexer )
32
32
from pandas .core .internals import BlockManager , make_block , form_blocks
33
33
from pandas .core .series import Series , _radd_compat
34
+ import pandas .core .expressions as expressions
34
35
from pandas .compat .scipy import scoreatpercentile as _quantile
35
36
from pandas .util .compat import OrderedDict
36
37
from pandas .util import py3compat
53
54
54
55
from pandas .core .config import get_option
55
56
56
-
57
57
#----------------------------------------------------------------------
58
58
# Docstring templates
59
59
@@ -186,10 +186,10 @@ class DataConflictError(Exception):
186
186
# Factory helper methods
187
187
188
188
189
- def _arith_method (op , name , default_axis = 'columns' ):
189
+ def _arith_method (op , name , str_rep = None , default_axis = 'columns' ):
190
190
def na_op (x , y ):
191
191
try :
192
- result = op ( x , y )
192
+ result = expressions . evaluate ( op , str_rep , x , y , raise_on_error = True )
193
193
except TypeError :
194
194
xrav = x .ravel ()
195
195
result = np .empty (x .size , dtype = x .dtype )
@@ -240,7 +240,7 @@ def f(self, other, axis=default_axis, level=None, fill_value=None):
240
240
return f
241
241
242
242
243
- def _flex_comp_method (op , name , default_axis = 'columns' ):
243
+ def _flex_comp_method (op , name , str_rep = None , default_axis = 'columns' ):
244
244
245
245
def na_op (x , y ):
246
246
try :
@@ -268,7 +268,7 @@ def na_op(x, y):
268
268
@Appender ('Wrapper for flexible comparison methods %s' % name )
269
269
def f (self , other , axis = default_axis , level = None ):
270
270
if isinstance (other , DataFrame ): # Another DataFrame
271
- return self ._flex_compare_frame (other , na_op , level )
271
+ return self ._flex_compare_frame (other , na_op , str_rep , level )
272
272
273
273
elif isinstance (other , Series ):
274
274
return self ._combine_series (other , na_op , None , axis , level )
@@ -294,7 +294,7 @@ def f(self, other, axis=default_axis, level=None):
294
294
casted = DataFrame (other , index = self .index ,
295
295
columns = self .columns )
296
296
297
- return self ._flex_compare_frame (casted , na_op , level )
297
+ return self ._flex_compare_frame (casted , na_op , str_rep , level )
298
298
299
299
else : # pragma: no cover
300
300
raise ValueError ("Bad argument shape" )
@@ -307,11 +307,11 @@ def f(self, other, axis=default_axis, level=None):
307
307
return f
308
308
309
309
310
- def _comp_method (func , name ):
310
+ def _comp_method (func , name , str_rep ):
311
311
@Appender ('Wrapper for comparison method %s' % name )
312
312
def f (self , other ):
313
313
if isinstance (other , DataFrame ): # Another DataFrame
314
- return self ._compare_frame (other , func )
314
+ return self ._compare_frame (other , func , str_rep )
315
315
elif isinstance (other , Series ):
316
316
return self ._combine_series_infer (other , func )
317
317
else :
@@ -750,26 +750,26 @@ def __contains__(self, key):
750
750
#----------------------------------------------------------------------
751
751
# Arithmetic methods
752
752
753
- add = _arith_method (operator .add , 'add' )
754
- mul = _arith_method (operator .mul , 'multiply' )
755
- sub = _arith_method (operator .sub , 'subtract' )
756
- div = divide = _arith_method (lambda x , y : x / y , 'divide' )
757
- pow = _arith_method (operator .pow , 'pow' )
753
+ add = _arith_method (operator .add , 'add' , '+' )
754
+ mul = _arith_method (operator .mul , 'multiply' , '*' )
755
+ sub = _arith_method (operator .sub , 'subtract' , '-' )
756
+ div = divide = _arith_method (lambda x , y : x / y , 'divide' , '/' )
757
+ pow = _arith_method (operator .pow , 'pow' , '**' )
758
758
759
759
radd = _arith_method (_radd_compat , 'radd' )
760
760
rmul = _arith_method (operator .mul , 'rmultiply' )
761
761
rsub = _arith_method (lambda x , y : y - x , 'rsubtract' )
762
762
rdiv = _arith_method (lambda x , y : y / x , 'rdivide' )
763
763
rpow = _arith_method (lambda x , y : y ** x , 'rpow' )
764
764
765
- __add__ = _arith_method (operator .add , '__add__' , default_axis = None )
766
- __sub__ = _arith_method (operator .sub , '__sub__' , default_axis = None )
767
- __mul__ = _arith_method (operator .mul , '__mul__' , default_axis = None )
768
- __truediv__ = _arith_method (operator .truediv , '__truediv__' ,
765
+ __add__ = _arith_method (operator .add , '__add__' , '+' , default_axis = None )
766
+ __sub__ = _arith_method (operator .sub , '__sub__' , '-' , default_axis = None )
767
+ __mul__ = _arith_method (operator .mul , '__mul__' , '*' , default_axis = None )
768
+ __truediv__ = _arith_method (operator .truediv , '__truediv__' , '/' ,
769
769
default_axis = None )
770
770
__floordiv__ = _arith_method (operator .floordiv , '__floordiv__' ,
771
771
default_axis = None )
772
- __pow__ = _arith_method (operator .pow , '__pow__' , default_axis = None )
772
+ __pow__ = _arith_method (operator .pow , '__pow__' , '**' , default_axis = None )
773
773
774
774
__radd__ = _arith_method (_radd_compat , '__radd__' , default_axis = None )
775
775
__rmul__ = _arith_method (operator .mul , '__rmul__' , default_axis = None )
@@ -782,13 +782,13 @@ def __contains__(self, key):
782
782
default_axis = None )
783
783
784
784
# boolean operators
785
- __and__ = _arith_method (operator .and_ , '__and__' )
786
- __or__ = _arith_method (operator .or_ , '__or__' )
785
+ __and__ = _arith_method (operator .and_ , '__and__' , '&' )
786
+ __or__ = _arith_method (operator .or_ , '__or__' , '|' )
787
787
__xor__ = _arith_method (operator .xor , '__xor__' )
788
788
789
789
# Python 2 division methods
790
790
if not py3compat .PY3 :
791
- __div__ = _arith_method (operator .div , '__div__' , default_axis = None )
791
+ __div__ = _arith_method (operator .div , '__div__' , '/' , default_axis = None )
792
792
__rdiv__ = _arith_method (lambda x , y : y / x , '__rdiv__' ,
793
793
default_axis = None )
794
794
@@ -801,19 +801,19 @@ def __invert__(self):
801
801
return self ._wrap_array (arr , self .axes , copy = False )
802
802
803
803
# Comparison methods
804
- __eq__ = _comp_method (operator .eq , '__eq__' )
805
- __ne__ = _comp_method (operator .ne , '__ne__' )
806
- __lt__ = _comp_method (operator .lt , '__lt__' )
807
- __gt__ = _comp_method (operator .gt , '__gt__' )
808
- __le__ = _comp_method (operator .le , '__le__' )
809
- __ge__ = _comp_method (operator .ge , '__ge__' )
810
-
811
- eq = _flex_comp_method (operator .eq , 'eq' )
812
- ne = _flex_comp_method (operator .ne , 'ne' )
813
- gt = _flex_comp_method (operator .gt , 'gt ' )
814
- lt = _flex_comp_method (operator .lt , 'lt ' )
815
- ge = _flex_comp_method (operator .ge , 'ge ' )
816
- le = _flex_comp_method (operator .le , 'le ' )
804
+ __eq__ = _comp_method (operator .eq , '__eq__' , '==' )
805
+ __ne__ = _comp_method (operator .ne , '__ne__' , '!=' )
806
+ __lt__ = _comp_method (operator .lt , '__lt__' , '<' )
807
+ __gt__ = _comp_method (operator .gt , '__gt__' , '>' )
808
+ __le__ = _comp_method (operator .le , '__le__' , '<=' )
809
+ __ge__ = _comp_method (operator .ge , '__ge__' , '>=' )
810
+
811
+ eq = _flex_comp_method (operator .eq , 'eq' , '==' )
812
+ ne = _flex_comp_method (operator .ne , 'ne' , '!=' )
813
+ lt = _flex_comp_method (operator .lt , 'lt' , '< ' )
814
+ gt = _flex_comp_method (operator .gt , 'gt' , '> ' )
815
+ le = _flex_comp_method (operator .le , 'le' , '<= ' )
816
+ ge = _flex_comp_method (operator .ge , 'ge' , '>= ' )
817
817
818
818
def dot (self , other ):
819
819
"""
@@ -1669,14 +1669,6 @@ def convert_objects(self, convert_dates=True, convert_numeric=False):
1669
1669
"""
1670
1670
return self ._constructor (self ._data .convert (convert_dates = convert_dates , convert_numeric = convert_numeric ))
1671
1671
1672
- def get_dtype_counts (self ):
1673
- """ return the counts of dtypes in this frame """
1674
- self ._consolidate_inplace ()
1675
- counts = dict ()
1676
- for b in self ._data .blocks :
1677
- counts [b .dtype .name ] = counts .get (b .dtype ,0 ) + b .shape [0 ]
1678
- return Series (counts )
1679
-
1680
1672
#----------------------------------------------------------------------
1681
1673
# properties for index and columns
1682
1674
@@ -3710,25 +3702,25 @@ def _combine_const(self, other, func, raise_on_error = True):
3710
3702
new_data = self ._data .eval (func , other , raise_on_error = raise_on_error )
3711
3703
return self ._constructor (new_data )
3712
3704
3713
- def _compare_frame (self , other , func ):
3705
+ def _compare_frame (self , other , func , str_rep ):
3714
3706
if not self ._indexed_same (other ):
3715
3707
raise Exception ('Can only compare identically-labeled '
3716
3708
'DataFrame objects' )
3717
3709
3718
- new_data = {}
3719
- for col in self .columns :
3720
- new_data [ col ] = func ( self [ col ] , other [ col ] )
3710
+ def _compare ( a , b ):
3711
+ return dict ([ ( col , func ( a [ col ], b [ col ])) for col in a .columns ])
3712
+ new_data = expressions . evaluate ( _compare , str_rep , self , other )
3721
3713
3722
3714
return self ._constructor (data = new_data , index = self .index ,
3723
3715
columns = self .columns , copy = False )
3724
3716
3725
- def _flex_compare_frame (self , other , func , level ):
3717
+ def _flex_compare_frame (self , other , func , str_rep , level ):
3726
3718
if not self ._indexed_same (other ):
3727
3719
self , other = self .align (other , 'outer' , level = level )
3728
3720
3729
- new_data = {}
3730
- for col in self .columns :
3731
- new_data [ col ] = func ( self [ col ] , other [ col ] )
3721
+ def _compare ( a , b ):
3722
+ return dict ([ ( col , func ( a [ col ], b [ col ])) for col in a .columns ])
3723
+ new_data = expressions . evaluate ( _compare , str_rep , self , other )
3732
3724
3733
3725
return self ._constructor (data = new_data , index = self .index ,
3734
3726
columns = self .columns , copy = False )
0 commit comments