pandas-dev/pandas · error · IndexError

Column(s) {self._selection} already selected

Error message

Column(s) {self._selection} already selected

What it means

Raised by SelectionMixin.__getitem__ when a selection has already been made on a groupby/resample/rolling-style object and you try to select again. After the first __getitem__, _selection is set; further indexing is rejected to prevent ambiguous chaining.

Source

Thrown at pandas/core/base.py:214

        return self._selected_obj.ndim

    @final
    @cache_readonly
    def _obj_with_exclusions(self):
        if isinstance(self.obj, ABCSeries):
            return self.obj

        if self._selection is not None:
            return self.obj[self._selection_list]

        if len(self.exclusions) > 0:
            return self.obj._drop_axis(self.exclusions, axis=1)
        else:
            return self.obj

    def __getitem__(self, key):
        if self._selection is not None:
            raise IndexError(f"Column(s) {self._selection} already selected")

        if isinstance(key, (list, tuple, ABCSeries, ABCIndex, np.ndarray)):
            if len(self.obj.columns.intersection(key)) != len(set(key)):
                bad_keys = list(set(key).difference(self.obj.columns))
                raise KeyError(f"Columns not found: {str(bad_keys)[1:-1]}")
            return self._gotitem(list(key), ndim=2)

        else:
            if key not in self.obj:
                raise KeyError(f"Column not found: {key}")
            ndim = self.obj[key].ndim
            return self._gotitem(key, ndim=ndim)

    def _gotitem(self, key, ndim: int, subset=None):
        """
        sub-classes to define
        return a sliced object

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Select all needed columns in a single __getitem__ pass: gb[['col1','col2']].
  2. Re-acquire the groupby object before a new selection.
  3. Restructure to select on the DataFrame before groupby.

Example fix

// before
g = df.groupby('g')['a']
g['b']  # raises

// after
g = df.groupby('g')[['a','b']]
Defensive patterns

Strategy: validation

Validate before calling

if getattr(obj, '_selection', None) is not None:
    raise IndexError('selection already made; re-acquire the holder to select again')

Type guard

def has_existing_selection(obj) -> bool:
    return getattr(obj, '_selection', None) is not None

Try / catch

try:
    sub = holder[key]
except IndexError as e:
    if 'already selected' in str(e):
        holder = rebuild_holder()  # re-acquire
        sub = holder[[existing, key]]
    else:
        raise

Prevention

When it happens

Trigger: `gb = df.groupby('g')['col1']; gb['col2']` — selecting a column after already subselection via __getitem__. Hit on objects mixing SelectionMixin like groupby column selection.

Common situations: Chained selections in groupby pipelines; refactoring selection logic into helper functions without resetting selection.

Related errors


AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07). Data as JSON: /api/errors/93cfa4d6d21fd84f. Report an issue: GitHub.