Skip to content

Why does CategoricalIndex.get_value call _convert_scalar_indexer? #31683

Closed
@jbrockmendel

Description

@jbrockmendel

cc @jreback @jorisvandenbossche @TomAugspurger the meat of CategoricalIndex.get_value reads:

def get_value(self, series, key):
        k = key
        try:
            k = self._convert_scalar_indexer(k, kind="getitem")
            indexer = self.get_loc(k)
            return series.take([indexer])[0]
        except (KeyError, TypeError):
            pass

        # we might be a positional inexer
        return Index.get_value(self, series, key)

The thing is, if we actually track down that _convert_scalar_indexer call, with kind="getitem" it always passes through to the base class method, which ends up checking:

            if kind == "getitem" and is_float(key):
                if not self.is_floating():
                    self._invalid_indexer("label", key)

But AFAICT CategoricalIndex.is_floating() is always False, so it looks like the call in get_value is a no-op, which I expect was not the original intention.

Also possibly undesired:

idx = pd.Index(range(4)).astype("f8") / 2
cidx = pd.CategoricalIndex(idx)

ser1 = pd.Series(range(4), index=idx)
ser2 = pd.Series(range(4), index=cidx)

>>> ser1[1.0] 
2
>>> ser2[1.0]
[...] TypeError [...]
>>> ser1[2]
[...] KeyError [...]
>>> ser2[2]
2

Can anyone confirm if the no-op call and/or different __getitem__ behavior is intentional?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions