Skip to content

BUG: cannot reindex on an axis with duplicate labels when using clique on coplanar points #897

@martinfleis

Description

@martinfleis
from shapely import Point
import geopandas as gpd
from libpysal.graph import Graph

Graph.build_kernel(gpd.GeoSeries(
        [
            Point(0, 0),
            Point(0, 0),
            Point(1, 0),
            Point(2, 0),
            Point(3, 0),
            Point(4, 0),
        ]
    ), k=2, coplanar="clique")

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[5], line 1
----> 1 Graph.build_kernel(gpd.GeoSeries(
      2         [
      3             Point(0, 0),
      4             Point(0, 0),
      5             Point(1, 0),
      6             Point(2, 0),
      7             Point(3, 0),
      8             Point(4, 0),
      9         ]
     10     ), k=2, coplanar="clique")

File ~/dev/pysal/gwlearn/.pixi/envs/default/lib/python3.13/site-packages/libpysal/graph/base.py:1120, in Graph.build_kernel(cls, data, kernel, k, bandwidth, metric, p, coplanar, taper, decay)
   1058 """Generate Graph from geometry data based on a kernel function
   1059 
   1060 Parameters
   (...)   1116     libpysal.graph.Graph encoding kernel weights
   1117 """
   1118 ids = _evaluate_index(data)
-> 1120 head, tail, weight = _kernel(
   1121     data,
   1122     bandwidth=bandwidth,
   1123     metric=metric,
   1124     kernel=kernel,
   1125     k=k,
   1126     p=p,
   1127     ids=ids,
   1128     coplanar=coplanar,
   1129     decay=decay,
   1130     taper=taper,
   1131 )
   1133 return cls.from_arrays(head, tail, weight)

File ~/dev/pysal/gwlearn/.pixi/envs/default/lib/python3.13/site-packages/libpysal/graph/_kernel.py:127, in _kernel(coordinates, bandwidth, metric, kernel, k, ids, p, taper, decay, coplanar, resolve_isolates, exclude_self_weights)
    125 if k is not None:
    126     if metric != "precomputed":
--> 127         d = _knn(coordinates, k=k, metric=metric, p=p, coplanar=coplanar)
    128     else:
    129         d = coordinates * (coordinates.argsort(axis=1, kind="stable") < (k + 1))

File ~/dev/pysal/gwlearn/.pixi/envs/default/lib/python3.13/site-packages/libpysal/graph/_kernel.py:249, in _knn(coordinates, metric, k, p, coplanar)
    247 adjtable["focal"] = ids[adjtable.focal]
    248 adjtable["neighbor"] = ids[adjtable.neighbor]
--> 249 adjtable = _reorder_adjtable_by_ids(adjtable, ids)
    250 sparse_out = sparse.csr_array(
    251     (
    252         adjtable.weight.values,
   (...)    255     shape=(n_samples, n_samples),
    256 )
    257 sparse_out.data[sparse_out.data < 0] = 0

File ~/dev/pysal/gwlearn/.pixi/envs/default/lib/python3.13/site-packages/libpysal/graph/_utils.py:283, in _reorder_adjtable_by_ids(adjtable, ids)
    280 def _reorder_adjtable_by_ids(adjtable, ids):
    281     return (
    282         adjtable.set_index(["focal", "neighbor"])
--> 283         .reindex(ids, level=0)
    284         .reindex(ids, level=1)
    285         .reset_index()
    286     )

File ~/dev/pysal/gwlearn/.pixi/envs/default/lib/python3.13/site-packages/pandas/core/frame.py:5400, in DataFrame.reindex(self, labels, index, columns, axis, method, copy, level, fill_value, limit, tolerance)
   5381 @doc(
   5382     NDFrame.reindex,
   5383     klass=_shared_doc_kwargs["klass"],
   (...)   5398     tolerance=None,
   5399 ) -> DataFrame:
-> 5400     return super().reindex(
   5401         labels=labels,
   5402         index=index,
   5403         columns=columns,
   5404         axis=axis,
   5405         method=method,
   5406         copy=copy,
   5407         level=level,
   5408         fill_value=fill_value,
   5409         limit=limit,
   5410         tolerance=tolerance,
   5411     )

File ~/dev/pysal/gwlearn/.pixi/envs/default/lib/python3.13/site-packages/pandas/core/generic.py:5632, in NDFrame.reindex(self, labels, index, columns, axis, method, copy, level, fill_value, limit, tolerance)
   5629     return self._reindex_multi(axes, copy, fill_value)
   5631 # perform the reindex on the axes
-> 5632 return self._reindex_axes(
   5633     axes, level, limit, tolerance, method, fill_value, copy
   5634 ).__finalize__(self, method="reindex")

File ~/dev/pysal/gwlearn/.pixi/envs/default/lib/python3.13/site-packages/pandas/core/generic.py:5660, in NDFrame._reindex_axes(self, axes, level, limit, tolerance, method, fill_value, copy)
   5655 new_index, indexer = ax.reindex(
   5656     labels, level=level, limit=limit, tolerance=tolerance, method=method
   5657 )
   5659 axis = self._get_axis_number(a)
-> 5660 obj = obj._reindex_with_indexers(
   5661     {axis: [new_index, indexer]},
...
   4326 # trying to reindex on an axis with duplicates
   4327 if not self._index_as_unique and len(indexer):
-> 4328     raise ValueError("cannot reindex on an axis with duplicate labels")

ValueError: cannot reindex on an axis with duplicate labels

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugfunctionality that: returns invalid, erroneous, or meaningless results; or doesn't work at all.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions