13
13
_get_combined_index )
14
14
from pandas .core .indexing import _NDFrameIndexer , _maybe_droplevels
15
15
from pandas .core .internals import BlockManager , make_block , form_blocks
16
+ from pandas .core .series import Series
16
17
from pandas .core .frame import DataFrame
17
18
from pandas .core .generic import NDFrame
18
19
from pandas .util import py3compat
@@ -104,7 +105,7 @@ def f(self, other):
104
105
105
106
def _panel_arith_method (op , name ):
106
107
@Substitution (op )
107
- def f (self , other , axis = 'items' ):
108
+ def f (self , other , axis = 0 ):
108
109
"""
109
110
Wrapper method for %s
110
111
@@ -123,6 +124,44 @@ def f(self, other, axis='items'):
123
124
f .__name__ = name
124
125
return f
125
126
127
+ def _comp_method (func , name ):
128
+
129
+ def na_op (x , y ):
130
+ try :
131
+ result = func (x , y )
132
+ except TypeError :
133
+ xrav = x .ravel ()
134
+ result = np .empty (x .size , dtype = x .dtype )
135
+ if isinstance (y , np .ndarray ):
136
+ yrav = y .ravel ()
137
+ mask = notnull (xrav ) & notnull (yrav )
138
+ result [mask ] = func (np .array (list (xrav [mask ])),
139
+ np .array (list (yrav [mask ])))
140
+ else :
141
+ mask = notnull (xrav )
142
+ result [mask ] = func (np .array (list (xrav [mask ])), y )
143
+
144
+ if func == operator .ne : # pragma: no cover
145
+ np .putmask (result , - mask , True )
146
+ else :
147
+ np .putmask (result , - mask , False )
148
+ result = result .reshape (x .shape )
149
+
150
+ return result
151
+
152
+ @Appender ('Wrapper for comparison method %s' % name )
153
+ def f (self , other ):
154
+ if isinstance (other , self ._constructor ):
155
+ return self ._compare_constructor (other , func )
156
+ elif isinstance (other , (self ._constructor_sliced , DataFrame , Series )):
157
+ raise Exception ("input needs alignment for this object [%s]" % self ._constructor )
158
+ else :
159
+ return self ._combine_const (other , na_op )
160
+
161
+
162
+ f .__name__ = name
163
+
164
+ return f
126
165
127
166
_agg_doc = """
128
167
Return %(desc)s over requested axis
@@ -280,7 +319,6 @@ def _init_dict(self, data, axes, dtype=None):
280
319
281
320
# shallow copy
282
321
arrays = []
283
- reshaped_data = data .copy ()
284
322
haxis_shape = [ len (a ) for a in raxes ]
285
323
for h in haxis :
286
324
v = values = data .get (h )
@@ -401,6 +439,51 @@ def __array_wrap__(self, result):
401
439
d ['copy' ] = False
402
440
return self ._constructor (result , ** d )
403
441
442
+ #----------------------------------------------------------------------
443
+ # Comparison methods
444
+
445
+ def _indexed_same (self , other ):
446
+ return all ([ getattr (self ,a ).equals (getattr (other ,a )) for a in self ._AXIS_ORDERS ])
447
+
448
+ def _compare_constructor (self , other , func ):
449
+ if not self ._indexed_same (other ):
450
+ raise Exception ('Can only compare identically-labeled '
451
+ 'same type objects' )
452
+
453
+ new_data = {}
454
+ for col in getattr (self ,self ._info_axis ):
455
+ new_data [col ] = func (self [col ], other [col ])
456
+
457
+ d = self ._construct_axes_dict ()
458
+ d ['copy' ] = False
459
+ return self ._constructor (data = new_data , ** d )
460
+
461
+ # boolean operators
462
+ __and__ = _arith_method (operator .and_ , '__and__' )
463
+ __or__ = _arith_method (operator .or_ , '__or__' )
464
+ __xor__ = _arith_method (operator .xor , '__xor__' )
465
+
466
+ def __neg__ (self ):
467
+ return - 1 * self
468
+
469
+ def __invert__ (self ):
470
+ return - 1 * self
471
+
472
+ # Comparison methods
473
+ __eq__ = _comp_method (operator .eq , '__eq__' )
474
+ __ne__ = _comp_method (operator .ne , '__ne__' )
475
+ __lt__ = _comp_method (operator .lt , '__lt__' )
476
+ __gt__ = _comp_method (operator .gt , '__gt__' )
477
+ __le__ = _comp_method (operator .le , '__le__' )
478
+ __ge__ = _comp_method (operator .ge , '__ge__' )
479
+
480
+ eq = _comp_method (operator .eq , 'eq' )
481
+ ne = _comp_method (operator .ne , 'ne' )
482
+ gt = _comp_method (operator .gt , 'gt' )
483
+ lt = _comp_method (operator .lt , 'lt' )
484
+ ge = _comp_method (operator .ge , 'ge' )
485
+ le = _comp_method (operator .le , 'le' )
486
+
404
487
#----------------------------------------------------------------------
405
488
# Magic methods
406
489
@@ -435,14 +518,14 @@ def __unicode__(self):
435
518
class_name = str (self .__class__ )
436
519
437
520
shape = self .shape
438
- dims = 'Dimensions: %s' % ' x ' .join ([ "%d (%s)" % (s , a ) for a ,s in zip (self ._AXIS_ORDERS ,shape ) ])
521
+ dims = u 'Dimensions: %s' % ' x ' .join ([ "%d (%s)" % (s , a ) for a ,s in zip (self ._AXIS_ORDERS ,shape ) ])
439
522
440
523
def axis_pretty (a ):
441
524
v = getattr (self ,a )
442
525
if len (v ) > 0 :
443
- return '%s axis: %s to %s' % (a .capitalize (),v [0 ], v [- 1 ])
526
+ return u '%s axis: %s to %s' % (a .capitalize (),com . pprint_thing ( v [0 ]), com . pprint_thing ( v [- 1 ]) )
444
527
else :
445
- return '%s axis: None' % a .capitalize ()
528
+ return u '%s axis: None' % a .capitalize ()
446
529
447
530
448
531
output = '\n ' .join ([class_name , dims ] + [axis_pretty (a ) for a in self ._AXIS_ORDERS ])
@@ -496,9 +579,9 @@ def ix(self):
496
579
return self ._ix
497
580
498
581
def _wrap_array (self , arr , axes , copy = False ):
499
- items , major , minor = axes
500
- return self . _constructor ( arr , items = items , major_axis = major ,
501
- minor_axis = minor , copy = copy )
582
+ d = dict ([ ( a , ax ) for a , ax in zip ( self . _AXIS_ORDERS , axes ) ])
583
+ d [ 'copy' ] = False
584
+ return self . _constructor ( arr , ** d )
502
585
503
586
fromDict = from_dict
504
587
@@ -742,7 +825,10 @@ def reindex(self, major=None, minor=None, method=None,
742
825
if (method is None and not self ._is_mixed_type and al <= 3 ):
743
826
items = kwargs .get ('items' )
744
827
if com ._count_not_none (items , major , minor ) == 3 :
745
- return self ._reindex_multi (items , major , minor )
828
+ try :
829
+ return self ._reindex_multi (items , major , minor )
830
+ except :
831
+ pass
746
832
747
833
if major is not None :
748
834
result = result ._reindex_axis (major , method , al - 2 , copy )
@@ -874,12 +960,12 @@ def _combine(self, other, func, axis=0):
874
960
elif isinstance (other , DataFrame ):
875
961
return self ._combine_frame (other , func , axis = axis )
876
962
elif np .isscalar (other ):
877
- new_values = func (self .values , other )
878
- d = self ._construct_axes_dict ()
879
- return self ._constructor (new_values , ** d )
963
+ return self ._combine_const (other , func )
880
964
881
- def __neg__ (self ):
882
- return - 1 * self
965
+ def _combine_const (self , other , func ):
966
+ new_values = func (self .values , other )
967
+ d = self ._construct_axes_dict ()
968
+ return self ._constructor (new_values , ** d )
883
969
884
970
def _combine_frame (self , other , func , axis = 0 ):
885
971
index , columns = self ._get_plane_axes (axis )
@@ -1434,8 +1520,8 @@ def update(self, other, join='left', overwrite=True, filter_func=None,
1434
1520
contain data in the same place.
1435
1521
"""
1436
1522
1437
- if not isinstance (other , Panel ):
1438
- other = Panel (other )
1523
+ if not isinstance (other , self . _constructor ):
1524
+ other = self . _constructor (other )
1439
1525
1440
1526
other = other .reindex (items = self .items )
1441
1527
0 commit comments