{"record":{"id":"298a4db0d687916a","repo":"pandas-dev/pandas","slug":"cannot-use-an-invert-condition-when-passing-to-num","errorCode":null,"errorMessage":"cannot use an invert condition when passing to numexpr","messagePattern":"cannot use an invert condition when passing to numexpr","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"pandas/core/computation/pytables.py","lineNumber":383,"sourceCode":"class JointFilterBinOp(FilterBinOp):\n    def format(self):\n        raise NotImplementedError(\"unable to collapse Joint Filters\")\n\n    # error: Signature of \"evaluate\" incompatible with supertype \"BinOp\"\n    def evaluate(self) -> Self:  # type: ignore[override]\n        return self\n\n\nclass ConditionBinOp(BinOp):\n    def __repr__(self) -> str:\n        return pprint_thing(f\"[Condition : [{self.condition}]]\")\n\n    def invert(self):\n        \"\"\"invert the condition\"\"\"\n        # if self.condition is not None:\n        #    self.condition = \"~(%s)\" % self.condition\n        # return self\n        raise NotImplementedError(\n            \"cannot use an invert condition when passing to numexpr\"\n        )\n\n    def format(self):\n        \"\"\"return the actual ne format\"\"\"\n        return self.condition\n\n    # error: Signature of \"evaluate\" incompatible with supertype \"BinOp\"\n    def evaluate(self) -> Self | None:  # type: ignore[override]\n        if not self.is_valid:\n            raise ValueError(f\"query term is not valid [{self}]\")\n\n        # convert values if we are in the table\n        if not self.is_in_table:\n            return None\n\n        rhs = self.conform(self.rhs)\n        values = [self.convert_value(v) for v in rhs]","sourceCodeStart":365,"sourceCodeEnd":401,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/computation/pytables.py#L365-L401","documentation":"Raised by ConditionBinOp.invert in pandas.core.computation.pytables. Conditions (ConditionBinOp) are translated into a numexpr string passed to PyTables; numexpr/PyTables cannot represent an arbitrary negation of a compiled condition, so calling .invert() on a ConditionBinOp raises NotImplementedError. It is triggered when a '~' (or 'not') wraps a condition that is destined for the numexpr path rather than the filter path.","triggerScenarios":"store.select('df', where='~(price > 100)') where 'price > 100' compiles to a numexpr condition; store.select('df', where='not (a == 5)') against a condition column. The invert is fine for FilterBinOps but not for conditions.","commonSituations":"Wanting the complement of a range/equality query; migrating SQL NOT semantics to pytables where; combining '~' with comparison operators.","solutions":["Rewrite the negation as a positive condition: '~(price > 100)' -> 'price <= 100'; '~(a == 5)' -> 'a != 5'.","Read the data and invert in pandas: df = store.get('df'); df[~(df['price'] > 100)].","If using list membership, prefer the '!=' filter path which does support inversion internally."],"exampleFix":"# before\nstore.select('df', where='~(price > 100)')  # NotImplementedError: cannot use an invert condition when passing to numexpr\n\n# after (rewrite positively)\nstore.select('df', where='price <= 100')\n# or invert in pandas\ndf = store.get('df')\ndf[~(df['price'] > 100)]","handlingStrategy":"validation","validationCode":"import re\n\ndef rewrite_inverted_condition(where: str) -> str:\n    # ~(a > X) -> a <= X ; ~(a < X) -> a >= X ; etc.\n    m = re.match(r'~\\s*\\(\\s*(\\w+)\\s*(>=|<=|>|<|==|!=)\\s*([^)]+)\\s*\\)\\s*$', where.strip())\n    if not m:\n        return where\n    col, op, val = m.groups()\n    invert = {'>': '<=', '<': '>=', '>=': '<', '<=': '>', '==': '!=', '!=': '=='}\n    return f'{col} {invert[op]} {val}'\n\nwhere = rewrite_inverted_condition(where)","typeGuard":null,"tryCatchPattern":"try:\n    store.select('df', where=where)\nexcept NotImplementedError as e:\n    if 'cannot use an invert condition' in str(e):\n        df = store.get('df')\n        result = df[~df.eval(where.replace('~', ''))]\n    else:\n        raise","preventionTips":["Rewrite '~(a OP b)' as the positive inverse (a INVOP b).","Use '!=' instead of '~(==)' for equality negation.","Fall back to in-pandas inversion for complex negations."],"tags":["pandas","hdf5","pytables","where","numexpr","inversion"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}