pandas-dev/pandas · warning · NotImplementedError

count not implemented with

Error message

count not implemented with {flags=}

What it means

_str_count dispatches to pyarrow.compute.count_substring_regex, which does not accept regex flags. If a non-zero flags argument is passed, pandas raises NotImplementedError rather than silently ignoring the flags or falling back to the slower object path.

Solutions

  1. Inline the flag into the pattern (e.g. '(?i)\d+') instead of using the flags argument.
  2. Convert to object dtype for the call: s.astype(object).str.count(pat, flags=...).
  3. Drop the flags argument if case sensitivity is acceptable.

Example fix

// before
s = pd.Series(["A1", "b2"], dtype="string[pyarrow]")
s.str.count(r"[a-z]", flags=re.IGNORECASE)
// after
s = pd.Series(["A1", "b2"], dtype="string[pyarrow]")
s.str.count(r"(?i)[a-z]")
Defensive patterns

Strategy: validation

Validate before calling

import re

def safe_str_count(s, pat, flags=0):
    if flags:
        # inline flags into the pattern
        flag_prefix = ""
        if flags & re.IGNORECASE: flag_prefix += "(?i)"
        if flags & re.MULTILINE: flag_prefix += "(?m)"
        if flags & re.DOTALL: flag_prefix += "(?s)"
        pat = flag_prefix + pat
    return s.str.count(pat)

Type guard

def flags_inlineable() -> bool:
    return True  # always preferred for arrow-backed str

Try / catch

try:
    s.str.count(pat, flags=flags)
except NotImplementedError:
    s.astype(object).str.count(pat, flags=flags)

Prevention

When it happens

Trigger: s.str.count(r'\d+', flags=re.IGNORECASE) on a string[pyarrow] Series — passing any non-zero int as flags.

Common situations: Porting regex calls that use re.IGNORECASE / re.MULTILINE; sharing flag constants between pandas str and re module code.

Related errors


AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11). Data as JSON: /api/errors/2f8a724418cee417. Report an issue: GitHub.

Appendix: source

Thrown at pandas/core/arrays/arrow/array.py:3647

                for val in chunk.to_numpy(zero_copy_only=False)
            ]
            for chunk in self._pa_array.iterchunks()
        ]

    def _convert_bool_result(self, result, na=lib.no_default, method_name=None):
        if na is not lib.no_default and not isna(na):  # pyright: ignore [reportGeneralTypeIssues]
            result = result.fill_null(na)
        return self._from_pyarrow_array(result)

    def _convert_int_result(self, result):
        return self._from_pyarrow_array(result)

    def _convert_rank_result(self, result):
        return self._from_pyarrow_array(result)

    def _str_count(self, pat: str, flags: int = 0) -> Self:
        if flags:
            raise NotImplementedError(f"count not implemented with {flags=}")
        return self._from_pyarrow_array(pc.count_substring_regex(self._pa_array, pat))

    def _str_repeat(self, repeats: int | Sequence[int]) -> Self:
        if not isinstance(repeats, int):
            raise NotImplementedError(
                f"repeat is not implemented when repeats is {type(repeats).__name__}"
            )
        return self._from_pyarrow_array(pc.binary_repeat(self._pa_array, repeats))

    def _str_join(self, sep: str) -> Self:
        if pa.types.is_string(self._pa_array.type) or pa.types.is_large_string(
            self._pa_array.type
        ):
            result = self._apply_elementwise(list)
            result = pa.chunked_array(result, type=pa.list_(pa.string()))
        else:
            result = self._pa_array
        return self._from_pyarrow_array(pc.binary_join(result, sep))

View on GitHub (pinned to 3b7651241d)