Construct PySal weights for rasters
    It drops weights for all cells that have no data or are Inf/NaN
    Usage:

    w = raster_weights(raster, rook=False, transform='r', **kwargs)

    where
        raster: (Masked) Numpy array for which weights are to be constructed
        rook: Boolean, type of contiguity. Default is queen. For rook, rook = True
        **kwargs are defined by and passed to pysal.lat2W.
        See help(pysal.lat2W)

def raster_weights(raster, rook=False, transform='r', **kwargs):
    """
    Construct PySal weights for rasters
    It drops weights for all cells that have no data or are Inf/NaN
    Usage:

    w = raster_weights(raster, rook=False, transform='r', **kwargs)

    where
        raster: (Masked) Numpy array for which weights are to be constructed
        rook: Boolean, type of contiguity. Default is queen. For rook, rook = True
        **kwargs are defined by and passed to pysal.lat2W.
        See help(pysal.lat2W)
    """
    rasterf = raster.flatten()
    if len(raster.shape) == 1:
        shape = (np.sqrt(raster.shape[0]) * np.array([1,1])).astype(int)
    else:
        shape = raster.shape
    w = pysal.lat2W(*shape, rook=rook, **kwargs)

    # Identify missing/no data
    if isinstance(rasterf, np.ma.core.MaskedArray):
        miss = rasterf.mask
    else:
        miss = np.logical_or(np.isnan(rasterf), np.isinf(rasterf))
    missn = set(np.arange(0, len(miss))[miss])

    cneighbors = {}
    for key, value in w.neighbors.items():
        if key not in missn:
            value = list(set(value).difference(missn))
            cneighbors[key] = value
    w = pysal.W(cneighbors)
    w.transform = transform
    return w