@@ -464,7 +464,6 @@ class Grouping:
464
464
465
465
_codes : npt .NDArray [np .signedinteger ] | None = None
466
466
_group_index : Index | None = None
467
- _passed_categorical : bool
468
467
_all_grouper : Categorical | None
469
468
_orig_cats : Index | None
470
469
_index : Index
@@ -483,7 +482,7 @@ def __init__(
483
482
) -> None :
484
483
self .level = level
485
484
self ._orig_grouper = grouper
486
- self . grouping_vector = _convert_grouper (index , grouper )
485
+ grouping_vector = _convert_grouper (index , grouper )
487
486
self ._all_grouper = None
488
487
self ._orig_cats = None
489
488
self ._index = index
@@ -494,8 +493,6 @@ def __init__(
494
493
self ._dropna = dropna
495
494
self ._uniques = uniques
496
495
497
- self ._passed_categorical = False
498
-
499
496
# we have a single grouper which may be a myriad of things,
500
497
# some of which are dependent on the passing in level
501
498
@@ -509,78 +506,83 @@ def __init__(
509
506
else :
510
507
index_level = index
511
508
512
- if self . grouping_vector is None :
513
- self . grouping_vector = index_level
509
+ if grouping_vector is None :
510
+ grouping_vector = index_level
514
511
else :
515
- mapper = self . grouping_vector
516
- self . grouping_vector = index_level .map (mapper )
512
+ mapper = grouping_vector
513
+ grouping_vector = index_level .map (mapper )
517
514
518
515
# a passed Grouper like, directly get the grouper in the same way
519
516
# as single grouper groupby, use the group_info to get codes
520
- elif isinstance (self . grouping_vector , Grouper ):
517
+ elif isinstance (grouping_vector , Grouper ):
521
518
# get the new grouper; we already have disambiguated
522
519
# what key/level refer to exactly, don't need to
523
520
# check again as we have by this point converted these
524
521
# to an actual value (rather than a pd.Grouper)
525
522
assert self .obj is not None # for mypy
526
- newgrouper , newobj = self .grouping_vector ._get_grouper (
527
- self .obj , validate = False
528
- )
523
+ newgrouper , newobj = grouping_vector ._get_grouper (self .obj , validate = False )
529
524
self .obj = newobj
530
525
531
- ng = newgrouper ._get_grouper ()
532
526
if isinstance (newgrouper , ops .BinGrouper ):
533
- # in this case we have `ng is newgrouper`
534
- self .grouping_vector = ng
527
+ # TODO: can we unwrap this and get a tighter typing
528
+ # for self.grouping_vector?
529
+ grouping_vector = newgrouper
535
530
else :
536
531
# ops.BaseGrouper
532
+ # TODO: 2023-02-03 no test cases with len(newgrouper.groupings) > 1.
533
+ # If that were to occur, would we be throwing out information?
534
+ # error: Cannot determine type of "grouping_vector" [has-type]
535
+ ng = newgrouper .groupings [0 ].grouping_vector # type: ignore[has-type]
537
536
# use Index instead of ndarray so we can recover the name
538
- self . grouping_vector = Index (ng , name = newgrouper .result_index .name )
537
+ grouping_vector = Index (ng , name = newgrouper .result_index .name )
539
538
540
539
elif not isinstance (
541
- self . grouping_vector , (Series , Index , ExtensionArray , np .ndarray )
540
+ grouping_vector , (Series , Index , ExtensionArray , np .ndarray )
542
541
):
543
542
# no level passed
544
- if getattr (self . grouping_vector , "ndim" , 1 ) != 1 :
545
- t = self . name or str (type (self . grouping_vector ))
543
+ if getattr (grouping_vector , "ndim" , 1 ) != 1 :
544
+ t = str (type (grouping_vector ))
546
545
raise ValueError (f"Grouper for '{ t } ' not 1-dimensional" )
547
546
548
- self . grouping_vector = index .map (self . grouping_vector )
547
+ grouping_vector = index .map (grouping_vector )
549
548
550
549
if not (
551
- hasattr (self . grouping_vector , "__len__" )
552
- and len (self . grouping_vector ) == len (index )
550
+ hasattr (grouping_vector , "__len__" )
551
+ and len (grouping_vector ) == len (index )
553
552
):
554
- grper = pprint_thing (self . grouping_vector )
553
+ grper = pprint_thing (grouping_vector )
555
554
errmsg = (
556
555
"Grouper result violates len(labels) == "
557
556
f"len(data)\n result: { grper } "
558
557
)
559
- self .grouping_vector = None # Try for sanity
560
558
raise AssertionError (errmsg )
561
559
562
- if isinstance (self . grouping_vector , np .ndarray ):
563
- if self . grouping_vector .dtype .kind in ["m" , "M" ]:
560
+ if isinstance (grouping_vector , np .ndarray ):
561
+ if grouping_vector .dtype .kind in ["m" , "M" ]:
564
562
# if we have a date/time-like grouper, make sure that we have
565
563
# Timestamps like
566
564
# TODO 2022-10-08 we only have one test that gets here and
567
565
# values are already in nanoseconds in that case.
568
- self . grouping_vector = Series (self . grouping_vector ).to_numpy ()
569
- elif is_categorical_dtype (self . grouping_vector ):
566
+ grouping_vector = Series (grouping_vector ).to_numpy ()
567
+ elif is_categorical_dtype (grouping_vector ):
570
568
# a passed Categorical
571
- self ._passed_categorical = True
572
-
573
- self ._orig_cats = self .grouping_vector .categories
574
- self .grouping_vector , self ._all_grouper = recode_for_groupby (
575
- self .grouping_vector , sort , observed
569
+ self ._orig_cats = grouping_vector .categories
570
+ grouping_vector , self ._all_grouper = recode_for_groupby (
571
+ grouping_vector , sort , observed
576
572
)
577
573
574
+ self .grouping_vector = grouping_vector
575
+
578
576
def __repr__ (self ) -> str :
579
577
return f"Grouping({ self .name } )"
580
578
581
579
def __iter__ (self ) -> Iterator :
582
580
return iter (self .indices )
583
581
582
+ @cache_readonly
583
+ def _passed_categorical (self ) -> bool :
584
+ return is_categorical_dtype (self .grouping_vector )
585
+
584
586
@cache_readonly
585
587
def name (self ) -> Hashable :
586
588
ilevel = self ._ilevel
0 commit comments