def test_limit_range(self): assert list(mm.limit_range(range(10), rng=(25, 75))) == [2, 3, 4, 5, 6, 7] assert list(mm.limit_range(range(10), rng=(10, 90))) == [1, 2, 3, 4, 5, 6, 7, 8] assert list(mm.limit_range([0, 1], rng=(25, 75))) == [0, 1] assert list( mm.limit_range(np.array([0, 1, 2, 3, 4, np.nan]), rng=(25, 75)) ) == [1, 2, 3]
def __init__(self, gdf, values, spatial_weights, unique_id, rng=None, verbose=True): try: from inequality.gini import Gini except ImportError: raise ImportError("The 'inequality' package is required.") self.gdf = gdf self.sw = spatial_weights self.id = gdf[unique_id] self.rng = rng data = gdf.copy() if values is not None: if not isinstance(values, str): data["mm_v"] = values values = "mm_v" self.values = data[values] if self.values.min() < 0: raise ValueError( "Values contain negative numbers. Normalise data before" "using momepy.Gini.") data = data.set_index(unique_id)[values] if rng: from momepy import limit_range results_list = [] for index in tqdm(data.index, total=data.shape[0], disable=not verbose): if index in spatial_weights.neighbors.keys(): neighbours = spatial_weights.neighbors[index].copy() if neighbours: neighbours.append(index) values_list = data.loc[neighbours].values if rng: values_list = limit_range(values_list, rng=rng) results_list.append(Gini(values_list).g) else: results_list.append(0) else: results_list.append(np.nan) self.series = pd.Series(results_list, index=gdf.index)
def __init__(self, gdf, values, spatial_weights, unique_id, rng=None, mode="mean"): self.gdf = gdf self.sw = spatial_weights self.id = gdf[unique_id] self.rng = rng self.mode = mode data = gdf.copy() if values is not None: if not isinstance(values, str): data["mm_v"] = values values = "mm_v" self.values = data[values] data = data.set_index(unique_id) results_list = [] for index, row in tqdm(data.iterrows(), total=data.shape[0]): neighbours = spatial_weights.neighbors[index].copy() if neighbours: neighbours.append(index) else: neighbours = [index] values_list = data.loc[neighbours][values] if rng: from momepy import limit_range values_list = limit_range(values_list, rng=rng) if mode == "mean": results_list.append(np.mean(values_list)) elif mode == "median": results_list.append(np.median(values_list)) elif mode == "mode": results_list.append(sp.stats.mode(values_list)[0][0]) else: raise ValueError("{} is not supported as mode.".format(mode)) self.series = pd.Series(results_list, index=gdf.index)
def __init__(self, gdf, values, spatial_weights, unique_id, rng=None, verbose=True): try: from inequality.theil import Theil except ImportError: raise ImportError("The 'inequality' package is required.") self.gdf = gdf self.sw = spatial_weights self.id = gdf[unique_id] self.rng = rng data = gdf.copy() if values is not None: if not isinstance(values, str): data["mm_v"] = values values = "mm_v" self.values = data[values] data = data.set_index(unique_id)[values] if rng: from momepy import limit_range results_list = [] for index in tqdm(data.index, total=data.shape[0], disable=not verbose): if index in spatial_weights.neighbors.keys(): neighbours = [index] neighbours += spatial_weights.neighbors[index] values_list = data.loc[neighbours] if rng: values_list = limit_range(values_list, rng=rng) results_list.append(Theil(values_list).T) else: results_list.append(np.nan) self.series = pd.Series(results_list, index=gdf.index)
def __init__(self, gdf, values, spatial_weights, unique_id, rng=None): try: from inequality.theil import Theil except ImportError: try: from pysal.explore.inequality.theil import Theil except ImportError: raise ImportError("The 'inequality' or 'pysal' package is required.") self.gdf = gdf self.sw = spatial_weights self.id = gdf[unique_id] self.rng = rng data = gdf.copy() if values is not None: if not isinstance(values, str): data["mm_v"] = values values = "mm_v" self.values = data[values] data = data.set_index(unique_id) results_list = [] for index, row in tqdm(data.iterrows(), total=data.shape[0]): neighbours = spatial_weights.neighbors[index].copy() if neighbours: neighbours.append(index) else: neighbours = [index] values_list = data.loc[neighbours][values] if rng: from momepy import limit_range values_list = limit_range(values_list, rng=rng) results_list.append(Theil(values_list).T) self.series = pd.Series(results_list, index=gdf.index)
def __init__( self, gdf, values, spatial_weights, unique_id, rng=None, mode="all", verbose=True, ): self.gdf = gdf self.sw = spatial_weights self.id = gdf[unique_id] self.rng = rng self.modes = mode if rng: from momepy import limit_range data = gdf.copy() if values is not None: if not isinstance(values, str): data["mm_v"] = values values = "mm_v" self.values = data[values] data = data.set_index(unique_id)[values] means = [] medians = [] modes = [] allowed = ["mean", "median", "mode"] if mode == "all": mode = allowed elif isinstance(mode, list): for m in mode: if m not in allowed: raise ValueError( "{} is not supported as mode.".format(mode)) elif isinstance(mode, str): if mode not in allowed: raise ValueError("{} is not supported as mode.".format(mode)) mode = [mode] for index in tqdm(data.index, total=data.shape[0], disable=not verbose): if index in spatial_weights.neighbors.keys(): neighbours = [index] neighbours += spatial_weights.neighbors[index] values_list = data.loc[neighbours] if rng: values_list = limit_range(values_list, rng=rng) if "mean" in mode: means.append(np.mean(values_list)) if "median" in mode: medians.append(np.median(values_list)) if "mode" in mode: modes.append(sp.stats.mode(values_list)[0][0]) else: if "mean" in mode: means.append(np.nan) if "median" in mode: medians.append(np.nan) if "mode" in mode: modes.append(np.nan) if "mean" in mode: self.series = self.mean = pd.Series(means, index=gdf.index) if "median" in mode: self.median = pd.Series(medians, index=gdf.index) if "mode" in mode: self.mode = pd.Series(modes, index=gdf.index)
def test_limit_range(self): assert mm.limit_range(range(10), rng=(25, 75)) == [3, 4, 5, 6] assert mm.limit_range(range(10), rng=(10, 90)) == [1, 2, 3, 4, 5, 6, 7, 8]
def theil(objects, values, spatial_weights=None, order=None, rng=(0, 100)): """ Calculates the Theil measure of inequality of values within k steps of morphological tessellation Uses `pysal.explore.inequality.theil.Theil` under the hood. .. math:: Parameters ---------- objects : GeoDataFrame GeoDataFrame containing morphological tessellation values : str, list, np.array, pd.Series the name of the dataframe column, np.array, or pd.Series where is stored character value. spatial_weights : libpysal.weights, optional spatial weights matrix - If None, Queen contiguity matrix of set order will be calculated based on objects. order : int order of Queen contiguity rng : Two-element sequence containing floats in range of [0,100], optional Percentiles over which to compute the range. Each must be between 0 and 100, inclusive. The order of the elements is not important. Returns ------- Series Series containing resulting values. References ---------- Examples -------- """ from pysal.explore.inequality.theil import Theil # define empty list for results results_list = [] print('Calculating Theil index...') if spatial_weights is None: print('Generating weights matrix (Queen) of {} topological steps...'.format(order)) from momepy import Queen_higher # matrix to define area of analysis (more steps) spatial_weights = Queen_higher(k=order, geodataframe=objects) else: if not all(objects.index == range(len(objects))): raise ValueError('Index is not consecutive range 0:x, spatial weights will not match objects.') if values is not None: if not isinstance(values, str): objects['mm_v'] = values values = 'mm_v' for index, row in tqdm(objects.iterrows(), total=objects.shape[0]): neighbours = spatial_weights.neighbors[index] values_list = objects.iloc[neighbours][values].tolist() if values_list: values_list.append(row[values]) else: values_list = [row[values]] if rng: from momepy import limit_range values_list = limit_range(values_list, rng=rng) results_list.append(Theil(values_list).T) series = pd.Series(results_list) if 'mm_v' in objects.columns: objects.drop(columns=['mm_v'], inplace=True) print('Theil index calculated.') return series