Skip to content

weights2gdf

cellseg_gsontools.links.weights2gdf(gdf, w, parallel=False)

Convert a libpysal weights object to a geopandas.GeoDataFrame.

Add class names and node centroids to the dataframe.

Note

if w.neighbors is empty, this will return None.

Parameters:

Name Type Description Default
gdf GeoDataFrame

GeoDataFrame of the nodes.

required
w W

PySAL weights object.

required
parallel bool, default=False

Whether to use parallel processing.

False

Returns:

Type Description
GeoDataFrame

gpd.GeoDataFrame: GeoDataFrame of the links.

Examples:

Convert libpysal weights from InterfaceContext to geopandas.GeoDataFrame.

>>> from cellseg_gsontools.spatial_context import InterfaceContext
>>> from cellseg_gsontools.links import weights2gdf
>>> iface_context = InterfaceContext(
...     area_gdf=areas,
...     cell_gdf=cells,
...     top_labels="area_cin",
...     bottom_labels="areastroma",
...     silence_warnings=True,
...     min_area_size=100000.0,
... )
>>> iface_context.fit(verbose=False)
>>> w = iface_context.context2weights("border_network")
>>> link_gdf = weights2gdf(cells, w)
Source code in cellseg_gsontools/links.py
def weights2gdf(
    gdf: gpd.GeoDataFrame, w: W, parallel: bool = False
) -> gpd.GeoDataFrame:
    """Convert a `libpysal` weights object to a `geopandas.GeoDataFrame`.

    Add class names and node centroids to the dataframe.

    Note:
        if `w.neighbors` is empty, this will return None.

    Parameters:
        gdf (gpd.GeoDataFrame):
            GeoDataFrame of the nodes.
        w (W):
            PySAL weights object.
        parallel (bool, default=False):
            Whether to use parallel processing.

    Returns:
        gpd.GeoDataFrame:
            GeoDataFrame of the links.

    Examples:
        Convert `libpysal` weights from `InterfaceContext` to `geopandas.GeoDataFrame`.
        >>> from cellseg_gsontools.spatial_context import InterfaceContext
        >>> from cellseg_gsontools.links import weights2gdf
        >>> iface_context = InterfaceContext(
        ...     area_gdf=areas,
        ...     cell_gdf=cells,
        ...     top_labels="area_cin",
        ...     bottom_labels="areastroma",
        ...     silence_warnings=True,
        ...     min_area_size=100000.0,
        ... )
        >>> iface_context.fit(verbose=False)
        >>> w = iface_context.context2weights("border_network")
        >>> link_gdf = weights2gdf(cells, w)
    """
    if not w.neighbors:
        return

    # get all possible link class combinations
    classes = sorted(gdf.class_name.unique().tolist())
    link_combos = get_link_combinations(classes)

    # init link gdf
    link_gdf = w.to_adjlist(remove_symmetric=True, drop_islands=True).reset_index()

    # add centroids and class names
    link_gdf.loc[:, "focal_centroid"] = gdf.loc[link_gdf.focal].centroid.to_list()
    link_gdf.loc[:, "neighbor_centroid"] = gdf.loc[link_gdf.neighbor].centroid.to_list()
    link_gdf.loc[:, "focal_class_name"] = gdf.loc[link_gdf.focal].class_name.to_list()
    link_gdf.loc[:, "neighbor_class_name"] = gdf.loc[
        link_gdf.neighbor
    ].class_name.to_list()

    func = partial(_get_link_class, link_combos=link_combos)
    link_gdf["class_name"] = gdf_apply(
        link_gdf,
        func=func,
        columns=["focal_class_name", "neighbor_class_name"],
        axis=1,
        parallel=parallel,
    )

    link_gdf["geometry"] = gdf_apply(
        link_gdf,
        func=_create_link,
        columns=["focal_centroid", "neighbor_centroid"],
        axis=1,
        parallel=parallel,
    )
    link_gdf = link_gdf.set_geometry("geometry")

    return link_gdf