{"record":{"id":"5fce744464fe8fe7","repo":"pandas-dev/pandas","slug":"duplicate-index-entries-are-not-allowed-in-to-coo","errorCode":null,"errorMessage":"Duplicate index entries are not allowed in to_coo transformation.","messagePattern":"Duplicate index entries are not allowed in to_coo transformation\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/sparse/scipy_sparse.py","lineNumber":159,"sourceCode":"\n\ndef sparse_series_to_coo(\n    ss: Series,\n    row_levels: Iterable[int] = (0,),\n    column_levels: Iterable[int] = (1,),\n    sort_labels: bool = False,\n) -> tuple[scipy.sparse.coo_matrix, list[IndexLabel], list[IndexLabel]]:\n    \"\"\"\n    Convert a sparse Series to a scipy.sparse.coo_matrix using index\n    levels row_levels, column_levels as the row and column\n    labels respectively. Returns the sparse_matrix, row and column labels.\n    \"\"\"\n    import scipy.sparse\n\n    if ss.index.nlevels < 2:\n        raise ValueError(\"to_coo requires MultiIndex with nlevels >= 2.\")\n    if not ss.index.is_unique:\n        raise ValueError(\n            \"Duplicate index entries are not allowed in to_coo transformation.\"\n        )\n\n    # to keep things simple, only rely on integer indexing (not labels)\n    row_levels = [ss.index._get_level_number(x) for x in row_levels]\n    column_levels = [ss.index._get_level_number(x) for x in column_levels]\n\n    v, i, j, rows, columns = _to_ijv(\n        ss, row_levels=row_levels, column_levels=column_levels, sort_labels=sort_labels\n    )\n    sparse_matrix = scipy.sparse.coo_matrix(\n        (v, (i, j)), shape=(len(rows), len(columns))\n    )\n    return sparse_matrix, rows, columns\n\n\ndef coo_to_sparse_series(\n    A: scipy.sparse.coo_matrix, dense_index: bool = False","sourceCodeStart":141,"sourceCodeEnd":177,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/arrays/sparse/scipy_sparse.py#L141-L177","documentation":"Thrown by sparse_series_to_coo in pandas/core/arrays/sparse/scipy_sparse.py:159 when the Series index has duplicate entries. The COO conversion maps each index tuple to a unique (row, col) coordinate; duplicates would alias cells and produce an ambiguous matrix, so pandas rejects them up front.","triggerScenarios":"Calling ss.sparse.to_coo() on a sparse Series whose MultiIndex contains repeated (row_label, col_label) tuples. Common after groupby/concat operations that retain non-unique indices.","commonSituations":"Index not reset after a groupby aggregation. Concatenating sparse Series without verify_integrity. Real-world data with duplicated composite keys fed straight into to_coo.","solutions":["Reset and rebuild a unique index: ss = ss.reset_index(drop=True); ss.index = pd.MultiIndex.from_arrays(...).","Aggregate duplicates first: ss = ss.groupby(level=list(range(ss.index.nlevels))).sum().","Check uniqueness beforehand: assert ss.index.is_unique."],"exampleFix":"// before\nss = pd.Series([1,2], index=pd.MultiIndex.from_tuples([('a','x'),('a','x')])).astype('Sparse[int]')\nss.sparse.to_coo()  # raises\n\n// after\nss = ss.groupby(level=[0,1]).sum()\nss.sparse.to_coo()","handlingStrategy":"validation","validationCode":"def unique_index_to_coo(ss, **kw):\n    if not ss.index.is_unique:\n        ss = ss.groupby(level=list(range(ss.index.nlevels))).sum()\n    return ss.sparse.to_coo(**kw)","typeGuard":"null","tryCatchPattern":"null","preventionTips":["Run ss.index.is_unique check before to_coo.","Reset_index and rebuild a unique MultiIndex after groupby/concat operations.","When concatenating sparse Series, pass verify_integrity=True."],"tags":["sparse","scipy","coo","duplicate-index"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}