{"record":{"id":"95ecfc95abe9b387","repo":"pandas-dev/pandas","slug":"cannot-combine-transform-and-aggregation-operation","errorCode":null,"errorMessage":"cannot combine transform and aggregation operations","messagePattern":"cannot combine transform and aggregation operations","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pandas/core/apply.py","lineNumber":540,"sourceCode":"            keys = selected_obj.columns.take(indices)  # type: ignore[assignment]\n\n        return keys, results\n\n    def wrap_results_list_like(\n        self, keys: Iterable[Hashable], results: list[Series | DataFrame]\n    ):\n        obj = self.obj\n\n        try:\n            return concat(results, keys=keys, axis=1, sort=False)\n        except TypeError as err:\n            # we are concatting non-NDFrame objects,\n            # e.g. a list of scalars\n            from pandas import Series\n\n            result = Series(results, index=keys, name=obj.name)\n            if is_nested_object(result):\n                raise ValueError(\n                    \"cannot combine transform and aggregation operations\"\n                ) from err\n            return result\n\n    def agg_dict_like(self) -> DataFrame | Series:\n        \"\"\"\n        Compute aggregation in the case of a dict-like argument.\n\n        Returns\n        -------\n        Result of aggregation.\n        \"\"\"\n        return self.agg_or_apply_dict_like(op_name=\"agg\")\n\n    def compute_dict_like(\n        self,\n        op_name: Literal[\"agg\", \"apply\"],\n        selected_obj: Series | DataFrame,","sourceCodeStart":522,"sourceCodeEnd":558,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/apply.py#L522-L558","documentation":"Raised inside `wrap_results_list_like` when concat of per-function results fails with TypeError and the resulting fallback Series is a 'nested object' — meaning some functions returned scalar aggregations while others returned NDFrame-shaped transforms. Mixing these two operation kinds in a single list-like call is structurally ambiguous.","triggerScenarios":"`df.agg(['sum', lambda s: s])` — `sum` aggregates to a scalar, the lambda returns same-shape Series (transform). The list mixes reduce and broadcast semantics, so pandas cannot decide the output shape.","commonSituations":"Combining named aggregations with custom element-wise functions in one list; copy-pasting a mixed function list from a tutorial; refactoring where a transform function slipped into an agg list.","solutions":["Separate the call into an aggregation pass and a transform pass: `df.agg(['sum', 'mean'])` then `df.transform([elemwise_fn])`.","Replace the offending function with one that consistently returns either scalars (for agg) or same-shaped output (for transform).","Use a dict form with explicit column→function mapping to make intent unambiguous."],"exampleFix":"# before\ndf.agg(['sum', lambda s: s + 1])\n# after\nagg_part = df.agg(['sum'])\ntrans_part = df.transform(lambda s: s + 1)","handlingStrategy":"validation","validationCode":"import pandas as pd\n\ndef classify(func, s):\n    out = func(s)\n    return 'transform' if isinstance(out, pd.Series) and out.index.equals(s.index) else 'agg'\n\ndef split_funcs(funcs, s):\n    agg, trans = [], []\n    for f in funcs:\n        (trans if classify(f, s) == 'transform' else agg).append(f)\n    return agg, trans","typeGuard":"def is_homogeneous_return(funcs, s) -> bool:\n    kinds = {classify(f, s) for f in funcs}\n    return len(kinds) == 1","tryCatchPattern":"try:\n    df.agg(funcs)\nexcept ValueError as e:\n    if 'cannot combine transform and aggregation' in str(e):\n        # split into agg and transform passes\n        ...\n    raise","preventionTips":["Do not mix scalar-returning and same-shape-returning functions in one list.","Split heterogeneous function lists into separate agg/transform calls."],"tags":["pandas","agg","transform","valueerror","mixed-operations"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}