pysal.lib.weights.spintW 源代码

"""
Spatial weights for spatial interaction including contiguity OD weights (ODW),
network based weights (netW), and distance-decay based vector weights (vecW).

"""

__author__ = "Taylor Oshan  <tayoshan@gmail.com> "

from scipy.sparse import kron
from .weights import W, WSP
from .distance import DistanceBand
from collections import OrderedDict

[文档]def ODW(Wo, Wd, transform='r', silence_warnings=True): """ Constructs an o*d by o*d origin-destination style spatial weight for o*d flows using standard spatial weights on o origins and d destinations. Input spatial weights must be binary or able to be sutiably transformed to binary. Parameters ---------- Wo : W object for origin locations o x o spatial weight object amongst o origins Wd : W object for destination locations d x d spatial weight object amongst d destinations transform : Transformation for standardization of final OD spatial weight; default is 'r' for row standardized Returns ------- W : spatial contiguity W object for assocations between flows o*d x o*d spatial weight object amongst o*d flows between o origins and d destinations Examples -------- >>> import pysal.lib >>> O = pysal.lib.weights.lat2W(2,2) >>> D = pysal.lib.weights.lat2W(2,2) >>> OD = pysal.lib.weights.spintW.ODW(O,D) >>> OD.weights[0] [0.25, 0.25, 0.25, 0.25] >>> OD.neighbors[0] array([ 5, 6, 9, 10], dtype=int32) >>> OD.full()[0][0] array([0. , 0. , 0. , 0. , 0. , 0.25, 0.25, 0. , 0. , 0.25, 0.25, 0. , 0. , 0. , 0. , 0. ]) """ if Wo.transform is not 'b': try: Wo.tranform = 'b' except: raise AttributeError('Wo is not binary and cannot be transformed to ' 'binary. Wo must be binary or suitably transformed to binary.') if Wd.transform is not 'b': try: Wd.tranform = 'b' except: raise AttributeError('Wd is not binary and cannot be transformed to ' 'binary. Wd must be binary or suitably transformed to binary.') Wo = Wo.sparse Wo.eliminate_zeros() Wd = Wd.sparse Wd.eliminate_zeros() Ww = kron(Wo, Wd, format='csr') Ww.eliminate_zeros() Ww = WSP(Ww).to_W(silence_warnings=silence_warnings) Ww.transform = transform return Ww
[文档]def netW(link_list, share='A', transform = 'r'): """ Create a network-contiguity based weight object based on different nodal relationships encoded in a network. Parameters ---------- link_list : list of tuples where each tuple is of the form (o,d) where o is an origin id and d is a destination id share : string denoting how to define the nodal relationship used to determine neighboring edges; defualt is 'A' for any shared nodes between two network edges; options include: 'A': any shared nodes 'O': a shared origin node 'D': a shared destination node 'OD' a shared origin node or a shared destination node 'C': a shared node that is the destination of the first edge and the origin of the second edge - i.e., a directed chain is formed moving from edge one to edge two. transform : Transformation for standardization of final OD spatial weight; default is 'r' for row standardized Returns ------- W : nodal contiguity W object for networkd edges or flows W Object representing the binary adjacency of the network edges given a definition of nodal relationshipysal.lib.weights.spintW. Examples -------- >>> import pysal.lib >>> links = [('a','b'), ('a','c'), ('a','d'), ('c','d'), ('c', 'b'), ('c','a')] >>> O = pysal.lib.weights.spintW.netW(links, share='O') >>> O.neighbors[('a', 'b')] [('a', 'c'), ('a', 'd')] >>> OD = pysal.lib.weights.spintW.netW(links, share='OD') >>> OD.neighbors[('a', 'b')] [('a', 'c'), ('a', 'd'), ('c', 'b')] >>> any_common = pysal.lib.weights.spintW.netW(links, share='A') >>> any_common.neighbors[('a', 'b')] [('a', 'c'), ('a', 'd'), ('c', 'b'), ('c', 'a')] """ neighbors = {} neighbors = OrderedDict() edges = link_list for key in edges: neighbors[key] = [] for neigh in edges: if key == neigh: continue if share.upper() == 'OD': if key[0] == neigh[0] or key[1] == neigh[1]: neighbors[key].append(neigh) elif share.upper() == 'O': if key[0] == neigh[0]: neighbors[key].append(neigh) elif share.upper() == 'D': if key[1] == neigh[1]: neighbors[key].append(neigh) elif share.upper() == 'C': if key[1] == neigh[0]: neighbors[key].append(neigh) elif share.upper() == 'A': if key[0] == neigh[0] or key[0] == neigh[1] or \ key[1] == neigh[0] or key[1] == neigh[1]: neighbors[key].append(neigh) else: raise AttributeError("Parameter 'share' must be 'O', 'D'," " 'OD', or 'C'") netW = W(neighbors) netW.tranform = transform return netW
[文档]def vecW(origin_x, origin_y, dest_x, dest_y, threshold, p=2, alpha=-1.0, binary=True, ids=None, build_sp=False, silence_warnings=False): """ Distance-based spatial weight for vectors that is computed using a 4-dimensional distance between the origin x,y-coordinates and the destination x,y-coordinates Parameters ---------- origin_x : list or array of vector origin x-coordinates origin_y : list or array of vector origin y-coordinates dest_x : list or array of vector destination x-coordinates dest_y : list or array of vector destination y-coordinates threshold : float distance band p : float Minkowski p-norm distance metric parameter: 1<=p<=infinity 2: Euclidean distance 1: Manhattan distance binary : boolean If true w_{ij}=1 if d_{i,j}<=threshold, otherwise w_{i,j}=0 If false wij=dij^{alpha} alpha : float distance decay parameter for weight (default -1.0) if alpha is positive the weights will not decline with distance. If binary is True, alpha is ignored ids : list values to use for keys of the neighbors and weights dicts build_sp : boolean True to build sparse distance matrix and false to build dense distance matrix; significant speed gains may be obtained dending on the sparsity of the of distance_matrix and threshold that is applied silence_warnings : boolean By default PySAL will print a warning if the dataset contains any disconnected observations or islands. To silence this warning set this parameter to True. Returns ------ W : DistanceBand W object that uses 4-dimenional distances between vectors origin and destination coordinates. Examples -------- >>> import pysal.lib >>> x1 = [5,6,3] >>> y1 = [1,8,5] >>> x2 = [2,4,9] >>> y2 = [3,6,1] >>> W1 = pysal.lib.weights.spintW.vecW(x1, y1, x2, y2, threshold=999) >>> list(W1.neighbors[0]) [1, 2] >>> W2 = pysal.lib.weights.spintW.vecW(x1, y2, x1, y2, threshold=8.5) >>> list(W2.neighbors[0]) [1, 2] """ data = list(zip(origin_x, origin_y, dest_x, dest_y)) W = DistanceBand(data, threshold=threshold, p=p, binary=binary, alpha=alpha, ids=ids, build_sp=False, silence_warnings=silence_warnings) return W
[文档]def mat2L(edge_matrix): """ Convert a matrix denoting network connectivity (edges or flows) to a list denoting edges Parameters ---------- edge_matrix : array where rows denote network edge origins, columns denote network edge destinations, and non-zero entries denote the existence of an edge between a given origin and destination Returns ------- edge_list : list of tuples where each tuple is of the form (o,d) where o is an origin id and d is a destination id """ if len(edge_matrix.shape) !=2: raise AttributeError("Matrix of network edges should be two dimensions" "with edge origins on one axis and edge destinations on the" "second axis with non-zero matrix entires denoting an edge" "between and origin and destination") edge_list = [] rows, cols = edge_matrix.shape for row in range(rows): for col in range(cols): if edge_matrix[row, col] != 0: edge_list.append((row,col)) return edge_list