Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API: Change the handling of IDs in from_dataframe constructors #477

Merged
merged 15 commits into from
Jan 10, 2023
67 changes: 54 additions & 13 deletions libpysal/weights/contiguity.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ def from_dataframe(
an ordered list of ids to use to index the spatial weights
object. If used, the resulting weights object will iterate
over results in the order of the names provided in this
argument.
argument.

See Also
--------
Expand All @@ -182,6 +182,47 @@ def from_dataframe(
df[geom_col].tolist(), ids=ids, id_order=id_order, **kwargs
)

@classmethod
def from_dataframe_new(cls, df, geom_col=None, ids=None, **kwargs):
"""
Construct a weights object from a (geo)pandas (Geo)DataFrame
with a geometry column.

Parameters
----------
df : DataFrame
a :class: `pandas.DataFrame` containing geometries to use
for spatial weights
geom_col : string
the name of the column in `df` that contains the
geometries. Defaults to active geometry column.
ids : str, list, np.array, pd.Series (default None)
A definition of ids to use to index the spatial weights object.
Could be the name of the dataframe column, `list`, `numpy.array`,
or `pandas.Series`. If `list`, `numpy.array` or
`pandas.Series` are used then it must have same length as dataframe.

**kwargs : dict
Additional arguments to be passed on to the W constructor


See Also
--------
:class:`libpysal.weights.weights.W`
:class:`libpysal.weights.contiguity.Rook`
"""

if geom_col is None:
geom_col = df.geometry.name

if isinstance(ids, str):
ids = df[ids]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not using get here as if you pass a string that does not match a column name we should raise an informative warning. The current code above gives AttributeError: 'NoneType' object has no attribute 'tolist', this one gives KeyError: 'missing', which is sensible enough.


if not isinstance(ids, list):
ids = ids.tolist()
martinfleis marked this conversation as resolved.
Show resolved Hide resolved

return cls.from_iterable(df[geom_col].tolist(), ids=ids, **kwargs)

@classmethod
def from_xarray(
cls,
Expand Down Expand Up @@ -227,7 +268,7 @@ def from_xarray(
Returns
-------
w : libpysal.weights.W/libpysal.weights.WSP
instance of spatial weights class W or WSP with an index attribute
instance of spatial weights class W or WSP with an index attribute

Notes
-----
Expand Down Expand Up @@ -382,7 +423,7 @@ def from_dataframe(cls, df, geom_col=None, **kwargs):
an ordered list of ids to use to index the spatial weights
object. If used, the resulting weights object will iterate
over results in the order of the names provided in this
argument.
argument.

See Also
--------
Expand Down Expand Up @@ -457,7 +498,7 @@ def from_xarray(
Returns
-------
w : libpysal.weights.W/libpysal.weights.WSP
instance of spatial weights class W or WSP with an index attribute
instance of spatial weights class W or WSP with an index attribute

Notes
-----
Expand Down Expand Up @@ -526,17 +567,17 @@ def Voronoi(points, criterion="rook", clip="ahull", **kwargs):

def _from_dataframe(df, **kwargs):
"""
Construct a voronoi contiguity weight directly from a dataframe.
Construct a voronoi contiguity weight directly from a dataframe.
Note that if criterion='rook', this is identical to the delaunay
graph for the points.
graph for the points.
martinfleis marked this conversation as resolved.
Show resolved Hide resolved

If the input dataframe is of any other geometry type than "Point",
a value error is raised.
a value error is raised.

Parameters
----------
df : pandas.DataFrame
dataframe containing point geometries for a
dataframe containing point geometries for a
voronoi diagram.

Returns
Expand All @@ -561,27 +602,27 @@ def _from_dataframe(df, **kwargs):

def _build(polygons, criterion="rook", ids=None):
"""
This is a developer-facing function to construct a spatial weights object.
This is a developer-facing function to construct a spatial weights object.

Parameters
----------
polygons : list
list of pysal polygons to use to build contiguity
criterion : string
option of which kind of contiguity to build. Is either "rook" or "queen"
option of which kind of contiguity to build. Is either "rook" or "queen"
ids : list
list of ids to use to index the neighbor dictionary

Returns
-------
tuple containing (neighbors, ids), where neighbors is a dictionary
describing contiguity relations and ids is the list of ids used to index
that dictionary.
that dictionary.

NOTE: this is different from the prior behavior of buildContiguity, which
returned an actual weights object. Since this just dispatches for the
classes above, this returns the raw ingredients for a spatial weights
object, not the object itself.
object, not the object itself.
"""
if ids and len(ids) != len(set(ids)):
raise ValueError(
Expand Down Expand Up @@ -621,7 +662,7 @@ def buildContiguity(polygons, criterion="rook", ids=None):
This is a deprecated function.

It builds a contiguity W from the polygons provided. As such, it is now
identical to calling the class constructors for Rook or Queen.
identical to calling the class constructors for Rook or Queen.
"""
# Warn('This function is deprecated. Please use the Rook or Queen classes',
# UserWarning)
Expand Down