{"record":{"id":"18c27b85705bf09a","repo":"pandas-dev/pandas","slug":"can-only-perform-ops-with-1-d-structures","errorCode":null,"errorMessage":"can only perform ops with 1-d structures","messagePattern":"can only perform ops with 1-d structures","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/masked.py","lineNumber":984,"sourceCode":"            )\n\n        if (\n            not hasattr(other, \"dtype\")\n            and is_list_like(other)\n            and len(other) == len(self)\n        ):\n            # Try inferring masked dtype instead of casting to object\n            other = pd_array(other)\n            other = extract_array(other, extract_numpy=True)\n\n        if isinstance(other, BaseMaskedArray):\n            other, omask = other._data, other._mask\n\n        elif is_list_like(other):\n            if not isinstance(other, ExtensionArray):\n                other = np.asarray(other)\n            if other.ndim > 1:\n                raise NotImplementedError(\"can only perform ops with 1-d structures\")\n\n        # We wrap the non-masked arithmetic logic used for numpy dtypes\n        #  in Series/Index arithmetic ops.\n        other = ops.maybe_prepare_scalar_for_op(other, (len(self),))\n        pd_op = ops.get_array_op(op)\n        other = ensure_wrapped_if_datetimelike(other)\n\n        if isinstance(other, ExtensionArray) and isinstance(other.dtype, ArrowDtype):\n            # GH#58602\n            return NotImplemented\n\n        if op_name in {\"pow\", \"rpow\"} and isinstance(other, np.bool_):\n            # Avoid DeprecationWarning: In future, it will be an error\n            #  for 'np.bool_' scalars to be interpreted as an index\n            #  e.g. test_array_scalar_like_equivalence\n            other = bool(other)\n\n        mask = self._propagate_mask(omask, other)","sourceCodeStart":966,"sourceCodeEnd":1002,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/masked.py#L966-L1002","documentation":"Raised by BaseMaskedArray._arith_method when the right-hand operand (other) is a list-like whose numpy conversion has ndim > 1. Masked array arithmetic is only defined for scalars or 1-D structures aligned elementwise with self; broadcasting against matrices/DataFrames is unsupported at this layer.","triggerScenarios":"Doing arr + matrix, arr * df.values (2-D), or arr op np.array([[..],[..]]) where the right operand converts to an ndarray with ndim>=2.","commonSituations":"Passing a 2-D numpy array or DataFrame where a Series/scalar was expected; refactoring elementwise ops to broadcast against a matrix; misusing a column vector (n,1) in place of a 1-D array.","solutions":["Flatten the operand to 1-D: arr + matrix.ravel() or arr + matrix[:, 0].","Operate through a Series/DataFrame so pandas handles alignment and broadcasting.","Squeeze a (n,1) array: arr + col_vector.squeeze(axis=1)."],"exampleFix":"// before\narr + np.array([[1, 2], [3, 4]])  # raises\n\n// after\narr + np.array([[1, 2], [3, 4]]).ravel()","handlingStrategy":"type-guard","validationCode":"import numpy as np\n\ndef ensure_1d(other):\n    arr = np.asarray(other)\n    if arr.ndim > 1:\n        arr = arr.reshape(-1)[:len(arr)] if arr.size else arr\n        arr = arr.ravel()\n    return arr","typeGuard":"def is_scalar_or_1d(other) -> bool:\n    import numpy as np\n    return np.isscalar(other) or (hasattr(other, 'ndim') and other.ndim == 1) or not hasattr(other, '__array__')","tryCatchPattern":"try:\n    res = arr + other\nexcept NotImplementedError as e:\n    if \"1-d structures\" in str(e):\n        res = arr + np.asarray(other).ravel()\n    else:\n        raise","preventionTips":["Validate operand ndim before masked-array arithmetic.","Flatten (n,1) column vectors with .squeeze(axis=1) or .ravel().","Prefer Series/DataFrame ops for multi-dimensional broadcasting."],"tags":["masked-array","arithmetic","ndim","broadcasting"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}