@@ -299,6 +299,8 @@ def from_array(cls, data):
299
299
"""
300
300
Make a Categorical type from a single array-like object.
301
301
302
+ For internal compatibility with numpy arrays.
303
+
302
304
Parameters
303
305
----------
304
306
data : array-like
@@ -412,7 +414,7 @@ def _get_levels(self):
412
414
413
415
levels = property (fget = _get_levels , fset = _set_levels , doc = _levels_doc )
414
416
415
- def reorder_levels (self , new_levels , ordered = None ):
417
+ def reorder_levels (self , new_levels , ordered = None , inplace = False ):
416
418
""" Reorders levels as specified in new_levels.
417
419
418
420
`new_levels` must include all old levels but can also include new level items. In
@@ -432,27 +434,50 @@ def reorder_levels(self, new_levels, ordered=None):
432
434
ordered : boolean, optional
433
435
Whether or not the categorical is treated as a ordered categorical. If not given,
434
436
do not change the ordered information.
437
+ inplace : bool (default: False)
438
+ Whether or not to reorder the levels inplace or return a copy of this categorical with
439
+ reordered levels.
440
+
441
+ Returns
442
+ -------
443
+ cat : Categorical with reordered levels.
435
444
"""
436
445
new_levels = self ._validate_levels (new_levels )
437
446
438
447
if len (new_levels ) < len (self ._levels ) or len (self ._levels .difference (new_levels )):
439
448
raise ValueError ('Reordered levels must include all original levels' )
440
- values = self .__array__ ()
441
- self ._codes = _get_codes_for_values (values , new_levels )
442
- self ._levels = new_levels
449
+
450
+ cat = self if inplace else self .copy ()
451
+ values = cat .__array__ ()
452
+ cat ._codes = _get_codes_for_values (values , new_levels )
453
+ cat ._levels = new_levels
443
454
if not ordered is None :
444
- self .ordered = ordered
455
+ cat .ordered = ordered
456
+ if not inplace :
457
+ return cat
445
458
446
- def remove_unused_levels (self ):
459
+ def remove_unused_levels (self , inplace = False ):
447
460
""" Removes levels which are not used.
448
461
449
- The level removal is done inplace.
462
+ Parameters
463
+ ----------
464
+ inplace : bool (default: False)
465
+ Whether or not to drop unused levels inplace or return a copy of this categorical with
466
+ unused levels dropped.
467
+
468
+ Returns
469
+ -------
470
+ cat : Categorical with unused levels dropped.
471
+
450
472
"""
451
- _used = sorted (np .unique (self ._codes ))
452
- new_levels = self .levels .take (com ._ensure_platform_int (_used ))
473
+ cat = self if inplace else self .copy ()
474
+ _used = sorted (np .unique (cat ._codes ))
475
+ new_levels = cat .levels .take (com ._ensure_platform_int (_used ))
453
476
new_levels = _ensure_index (new_levels )
454
- self ._codes = _get_codes_for_values (self .__array__ (), new_levels )
455
- self ._levels = new_levels
477
+ cat ._codes = _get_codes_for_values (cat .__array__ (), new_levels )
478
+ cat ._levels = new_levels
479
+ if not inplace :
480
+ return cat
456
481
457
482
458
483
__eq__ = _cat_compare_op ('__eq__' )
@@ -683,7 +708,14 @@ def view(self):
683
708
return self
684
709
685
710
def to_dense (self ):
686
- """ Return my 'dense' repr """
711
+ """Return my 'dense' representation
712
+
713
+ For internal compatibility with numpy arrays.
714
+
715
+ Returns
716
+ -------
717
+ dense : array
718
+ """
687
719
return np .asarray (self )
688
720
689
721
def fillna (self , fill_value = None , method = None , limit = None , ** kwargs ):
@@ -743,7 +775,10 @@ def fillna(self, fill_value=None, method=None, limit=None, **kwargs):
743
775
name = self .name , fastpath = True )
744
776
745
777
def take_nd (self , indexer , allow_fill = True , fill_value = None ):
746
- """ Take the codes by the indexer, fill with the fill_value. """
778
+ """ Take the codes by the indexer, fill with the fill_value.
779
+
780
+ For internal compatibility with numpy arrays.
781
+ """
747
782
748
783
# filling must always be None/nan here
749
784
# but is passed thru internally
@@ -757,7 +792,10 @@ def take_nd(self, indexer, allow_fill=True, fill_value=None):
757
792
take = take_nd
758
793
759
794
def _slice (self , slicer ):
760
- """ Return a slice of myself. """
795
+ """ Return a slice of myself.
796
+
797
+ For internal compatibility with numpy arrays.
798
+ """
761
799
762
800
# only allow 1 dimensional slicing, but can
763
801
# in a 2-d case be passd (slice(None),....)
@@ -771,19 +809,21 @@ def _slice(self, slicer):
771
809
name = self .name , fastpath = True )
772
810
773
811
def __len__ (self ):
812
+ """The length of this Categorical."""
774
813
return len (self ._codes )
775
814
776
815
def __iter__ (self ):
816
+ """Returns an Iterator over the values of this Categorical."""
777
817
return iter (np .array (self ))
778
818
779
- def _tidy_repr (self , max_vals = 20 ):
819
+ def _tidy_repr (self , max_vals = 10 ):
780
820
num = max_vals // 2
781
821
head = self [:num ]._get_repr (length = False , name = False , footer = False )
782
822
tail = self [- (max_vals - num ):]._get_repr (length = False ,
783
823
name = False ,
784
824
footer = False )
785
825
786
- result = '%s\n ...\n %s' % (head , tail )
826
+ result = '%s, ..., %s' % (head [: - 1 ] , tail [ 1 :] )
787
827
result = '%s\n %s' % (result , self ._repr_footer ())
788
828
789
829
return compat .text_type (result )
@@ -840,17 +880,14 @@ def _get_repr(self, name=False, length=True, na_rep='NaN', footer=True):
840
880
841
881
def __unicode__ (self ):
842
882
""" Unicode representation. """
843
- width , height = get_terminal_size ()
844
- max_rows = (height if get_option ("display.max_rows" ) == 0
845
- else get_option ("display.max_rows" ))
846
-
847
- if len (self ._codes ) > (max_rows or 1000 ):
848
- result = self ._tidy_repr (min (30 , max_rows ) - 4 )
883
+ _maxlen = 10
884
+ if len (self ._codes ) > _maxlen :
885
+ result = self ._tidy_repr (_maxlen )
849
886
elif len (self ._codes ) > 0 :
850
- result = self ._get_repr (length = len (self ) > 50 ,
887
+ result = self ._get_repr (length = len (self ) > _maxlen ,
851
888
name = True )
852
889
else :
853
- result = 'Categorical( [], %s' % self ._get_repr (name = True ,
890
+ result = '[], %s' % self ._get_repr (name = True ,
854
891
length = False ,
855
892
footer = True ,
856
893
).replace ("\n " ,", " )
@@ -1025,7 +1062,7 @@ def unique(self):
1025
1062
-------
1026
1063
unique values : array
1027
1064
"""
1028
- return self .levels
1065
+ return np . asarray ( self .levels )
1029
1066
1030
1067
def equals (self , other ):
1031
1068
"""
@@ -1113,8 +1150,11 @@ def _delegate_property_set(self, name, new_values):
1113
1150
return setattr (self .categorical , name , new_values )
1114
1151
1115
1152
def _delegate_method (self , name , * args , ** kwargs ):
1153
+ from pandas import Series
1116
1154
method = getattr (self .categorical , name )
1117
- return method (* args , ** kwargs )
1155
+ res = method (* args , ** kwargs )
1156
+ if not res is None :
1157
+ return Series (res , index = self .index )
1118
1158
1119
1159
CategoricalProperties ._add_delegate_accessors (delegate = Categorical ,
1120
1160
accessors = ["levels" , "ordered" ],
0 commit comments