11"""Compute multiscalar segregation profiles."""
22
33import warnings
4+ from warnings import warn
45
56import numpy as np
67import pandas as pd
7- from libpysal .weights import Kernel
8+ from libpysal .graph import Graph
89from pyproj .crs import CRS
910
1011
@@ -19,7 +20,8 @@ def compute_multiscalar_profile(
1920 decay = "linear" ,
2021 function = "triangular" ,
2122 precompute = True ,
22- ** kwargs
23+ check_crs = True ,
24+ ** kwargs ,
2325):
2426 """Compute multiscalar segregation profile.
2527
@@ -56,11 +58,13 @@ def compute_multiscalar_profile(
5658 precompute: bool
5759 Whether the pandana.Network instance should precompute the range
5860 queries. This is True by default
61+ check_crs:
62+ warn if geodataframe is not stored in WGS coordinates. Can help debug
63+ errors when computed index is zero indicating a poor merge. Default is True
5964 **kwargs : dict
6065 additional keyword arguments passed to each index (e.g. for setting a random
6166 seed in indices like ModifiedGini or ModifiedDissm)
6267
63-
6468 Returns
6569 -------
6670 pandas.Series
@@ -89,13 +93,16 @@ def compute_multiscalar_profile(
8993 with warnings .catch_warnings ():
9094 warnings .simplefilter ("ignore" )
9195 if network :
92- if not gdf .crs .equals (CRS (4326 )):
93- gdf = gdf .to_crs (epsg = 4326 )
96+ distances = np .array (distances ).astype (float )
97+ if check_crs :
98+ if not gdf .crs .equals (CRS (4326 )):
99+ warn (
100+ "GeoDataFrame is in CRS {gdf.crs}. Ensure your network is also stored in this system"
101+ )
94102 if precompute :
95103 maxdist = max (distances )
96104 network .precompute (maxdist )
97105 for distance in distances :
98- distance = np .float (distance )
99106 if group_pop_var :
100107 idx = segregation_index (
101108 gdf ,
@@ -105,7 +112,7 @@ def compute_multiscalar_profile(
105112 decay = decay ,
106113 distance = distance ,
107114 precompute = False ,
108- ** kwargs
115+ ** kwargs ,
109116 )
110117 elif groups :
111118 idx = segregation_index (
@@ -115,20 +122,33 @@ def compute_multiscalar_profile(
115122 decay = decay ,
116123 distance = distance ,
117124 precompute = False ,
118- ** kwargs
125+ ** kwargs ,
119126 )
120127
121128 indices [distance ] = idx .statistic
122129 else :
123130 for distance in distances :
124- w = Kernel .from_dataframe (gdf , bandwidth = distance , function = function )
131+ funcs = [
132+ "triangular" ,
133+ "parabolic" ,
134+ "gaussian" ,
135+ "bisquare" ,
136+ "cosine" ,
137+ "boxcar" ,
138+ "identity" ,
139+ ]
140+ if function not in funcs :
141+ raise ValueError (f"function must be one of { funcs } " )
142+ w = Graph .build_kernel (
143+ gdf .set_geometry (gdf .centroid ), bandwidth = distance , kernel = function
144+ ).to_W ()
125145 if group_pop_var :
126146 idx = segregation_index (
127147 gdf ,
128148 group_pop_var = group_pop_var ,
129149 total_pop_var = total_pop_var ,
130150 w = w ,
131- ** kwargs
151+ ** kwargs ,
132152 )
133153 else :
134154 idx = segregation_index (gdf , groups , w = w , ** kwargs )
0 commit comments