{"record":{"id":"249f19766e8cbd26","repo":"pandas-dev/pandas","slug":"function-did-not-transform","errorCode":null,"errorMessage":"Function did not transform","messagePattern":"Function did not transform","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pandas/core/apply.py","lineNumber":406,"sourceCode":"        try:\n            result = self.transform_str_or_callable(func)\n        except TypeError:\n            raise\n        except Exception as err:\n            raise ValueError(\"Transform function failed\") from err\n\n        # Functions that transform may return empty Series/DataFrame\n        # when the dtype is not appropriate\n        if (\n            isinstance(result, (ABCSeries, ABCDataFrame))\n            and result.empty\n            and not obj.empty\n        ):\n            raise ValueError(\"Transform function failed\")\n        if not isinstance(result, (ABCSeries, ABCDataFrame)) or not result.index.equals(\n            obj.index\n        ):\n            raise ValueError(\"Function did not transform\")\n\n        return result\n\n    def transform_dict_like(self, func) -> DataFrame:\n        \"\"\"\n        Compute transform in the case of a dict-like func\n        \"\"\"\n\n        obj = self.obj\n        args = self.args\n        kwargs = self.kwargs\n\n        # transform is currently only for Series/DataFrame\n        assert isinstance(obj, ABCNDFrame)\n\n        if len(func) == 0:\n            raise ValueError(\"No transform functions were provided\")\n","sourceCodeStart":388,"sourceCodeEnd":424,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/apply.py#L388-L424","documentation":"Raised inside `Apply.transform` when the function returns a value that is either not a Series/DataFrame or whose index does not match the input object's index. `transform` is contract-bound to return output with the same axis as the input (it must broadcast back); returning a scalar or a reindexed object violates this contract.","triggerScenarios":"`df.transform(lambda s: s.sum())` — returns a scalar per column, not same-length output. `df.transform(lambda s: s.reset_index(drop=True))` — breaks index alignment. Any function returning a length-mismatched or non-NDFrame object.","commonSituations":"Confusing `transform` with `agg` (the most common cause): developers use transform when they want a single aggregated value per group/column. Also functions that internally sort/reset the index, or that return Python primitives.","solutions":["If you want one value per group/column, use `agg` (or `apply`) instead of `transform`.","Ensure the function returns a Series with the same index as its input: e.g. `lambda s: s - s.mean()`.","Avoid index-mutating operations (reset_index, sort_values without restoring index) inside the transform function."],"exampleFix":"# before\ndf.groupby('g')['v'].transform(lambda s: s.sum())  # scalar per group\n# after\ndf.groupby('g')['v'].transform(lambda s: s.fillna(s.mean()))\n# or use agg for reduction\ndf.groupby('g')['v'].agg('sum')","handlingStrategy":"validation","validationCode":"import pandas as pd\n\ndef is_valid_transform(func, s):\n    \"\"\"Verify func returns same-index Series for transform contract.\"\"\"\n    out = func(s)\n    return isinstance(out, pd.Series) and out.index.equals(s.index)\n\nsample = df[df.columns[0]]\nif not is_valid_transform(my_func, sample):\n    # use agg instead\n    result = df.agg(my_func)\nelse:\n    df.transform(my_func)","typeGuard":"def preserves_index(out, original) -> bool:\n    import pandas as pd\n    return isinstance(out, pd.Series) and out.index.equals(original.index)","tryCatchPattern":"try:\n    df.transform(func)\nexcept ValueError as e:\n    if 'Function did not transform' in str(e):\n        df.agg(func)  # fall back to aggregation semantics\n    else:\n        raise","preventionTips":["Use `agg` when you want a scalar per group — `transform` requires same-shaped output.","Avoid reset_index/sort_values inside transform functions unless you restore the original index."],"tags":["pandas","transform","valueerror","contract","shape-mismatch"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}