示例#1
0
    def __calcWeight(self, layer, ids, searchDistance, valueColumn):
        # Weight 계산
        neighbors  = {}
        weights = {}
        dataList = []
        idList = []
        iPrg = 0
        for iID in ids:
            #iGeom = centroidDict[iID]
            iGeom = self.sourceRegions[iID]["centroid"]
            iRowNeighbors = []
            iRowWeights = []

            iPrg += 1
            self.progressBar.setValue(iPrg)
            forceGuiUpdate()

            for jID in ids:
                #jGeom = centroidDict[jID]
                jGeom = self.sourceRegions[jID]["centroid"]

                if iID == jID: # 같은 지역인 경우
                    pass
                else:
                    # searchDistance = 0 인 경우 MBR이 겹치면 인접으로 판단
                    # G 통계량의 Weight가 0 혹은 1만 허용해 Inverse Distance는 불가
                    if searchDistance <= 0:
                        iMbr = self.sourceRegions[iID]["mbr"]
                        jMbr = self.sourceRegions[jID]["mbr"]
                        # MBR이 아닌 지오메트리로 테스트 시 너무 잘 죽음
                        if iMbr.intersects(jMbr):
                            iRowNeighbors.append(jID)
                            iRowWeights.append(1)
                    else:
                        dist = iGeom.distance(jGeom)
                        if dist != 0.0 and dist <= searchDistance:
                            iRowNeighbors.append(jID)
                            iRowWeights.append(1)
            if (len(iRowNeighbors) > 0):
                neighbors[iID] = iRowNeighbors
                weights[iID] = iRowWeights
                iFeature = layer.getFeatures(QgsFeatureRequest(iID)).next()
                try:
                    val = float(iFeature[valueColumn])
                except TypeError:
                    val = 0.0
                dataList.append(val)
                idList.append(iID)

        w = W(neighbors, weights)
        y = np.array(dataList)
        self.localNeighbors[searchDistance] = neighbors

        return w, y
示例#2
0
    def __calcWeight(self, layer, ids, searchDistance, valueColumn):
        # Weight 계산
        neighbors = {}
        weights = {}
        dataList = []
        idList = []
        iPrg = 0
        for iID in ids:
            #iGeom = centroidDict[iID]
            iGeom = self.sourceRegions[iID]["centroid"]
            iRowNeighbors = []
            iRowWeights = []

            iPrg += 1
            self.progressBar.setValue(iPrg)
            forceGuiUpdate()

            for jID in ids:
                #jGeom = centroidDict[jID]
                jGeom = self.sourceRegions[jID]["centroid"]

                if iID == jID:  # 같은 지역인 경우
                    pass
                else:
                    dist = iGeom.distance(jGeom)
                    # searchDistance = 0 인 경우 InverseDist
                    if searchDistance <= 0:
                        if dist <= 0:
                            continue
                        iRowNeighbors.append(jID)
                        iRowWeights.append(1.0 / dist)
                    elif dist != 0.0 and dist <= searchDistance:
                        iRowNeighbors.append(jID)
                        iRowWeights.append(1)
            if (len(iRowNeighbors) > 0):
                neighbors[iID] = iRowNeighbors
                weights[iID] = iRowWeights
                iFeature = layer.getFeatures(QgsFeatureRequest(iID)).next()
                try:
                    val = float(iFeature[valueColumn])
                except TypeError:
                    val = 0.0
                dataList.append(val)
                idList.append(iID)

        w = W(neighbors, weights)
        y = np.array(dataList)
        self.localNeighbors[searchDistance] = neighbors

        return w, y
示例#3
0
def calc_moran_neib_data(lq, neighbors, weights):
    w = W(neighbors, weights, id_order = sorted(neighbors.keys()))
    for cluster in lq[list(lq.keys())[0]].keys():
        out = open("%s.csv" % cluster, 'w')
        out.write("year, mi.I, mi.EI, mi.seI_norm, mi.z_norm, mi.p_norm\n")
        for year in [ str(_) for _ in range(2009, 2017) ]:
            data = []
            for region in lq.keys():
                try:
                    data += [lq[region][cluster][year]]
                except KeyError as e:
                    print(e)
                    data += [-1]
            data = np.array(data)
            mi = Moran(data, w)
            out.write("%s,%s,%s,%s,%s,%s\n" % (year, mi.I, mi.EI, mi.seI_norm, mi.z_norm, mi.p_norm))
        out.close()
    def save_pysal_max_p(self):
        for floor in range(4, 15):
            weights = self.load_weights(5)
            print("Weights loaded k = %d" % 5)

            pysal_weights = W(weights[0], weights[1])
            attributes = self.get_attributes()

            print("Started clustering floor = %d" % floor)
            result = pysal.region.Maxp(pysal_weights,
                                       attributes,
                                       floor,
                                       self.floor_variable,
                                       verbose=True,
                                       initial=20)
            print("Ended clustering floor = %d.\nStarted dumping " % floor)

            pickle.dump(result,
                        open('clusters/cluster_floor_%d.pkl' % floor, 'wb'),
                        pickle.HIGHEST_PROTOCOL)
示例#5
0
def calc_moran_dist_data(lq, distances):
    from pysal import W, Moran
    regnames = sorted(set([ s.split('<->')[0] for s in distances.keys() ]))
    neighbors = {}
    weights   = {}
    f = open('/tmp/dist.csv','w')
    f.write("%s\n" % regnames)
    for i in range(len(regnames)):
        n_data, w_data = [], []
        for j in range(len(regnames)):
            if i != j:
                n_data += [j]
                try:
                    w = 1 / distances["%s<->%s" % (regnames[i], regnames[j])]
                except ZeroDivisionError:
                    w = 0
                w_data += [w]
                f.write("%s, " % w)
            else:
                f.write("%s, " % 0)
        f.write("\n")
        neighbors.update({str(i):n_data})
        weights.update({str(i):w_data})
    f.close()
    w = W(neighbors, weights, id_order = sorted(neighbors.keys()))
    for cluster in lq[list(lq.keys())[0]].keys():
        out = open("%s.dist.csv" % cluster, 'w')
        out.write("year, mi.I, mi.EI, mi.seI_norm, mi.z_norm, mi.p_norm\n")
        for year in [ str(_) for _ in range(2009, 2017) ]:
            data = []
            for region in lq.keys():
                try:
                    data += [lq[region][cluster][year]]
                except KeyError as e:
                    print(e)
                    data += [-1]
            data = np.array(data)
            mi = Moran(data, w)
            out.write("%s,%s,%s,%s,%s,%s\n" % (year, mi.I, mi.EI, mi.seI_norm, mi.z_norm, mi.p_norm))
        out.close()
示例#6
0
def calc_local_moran_dist_data(lq, distances):
    from pysal import W, Moran
    regnames = sorted(set([ s.split('<->')[0] for s in distances.keys() ]))
    neighbors = {}
    weights   = {}
    for i in range(len(regnames)):
        n_data, w_data = [], []
        for j in range(len(regnames)):
            if i != j:
                n_data += [j]
                try:
                    w = 1 / distances["%s<->%s" % (regnames[i], regnames[j])]
                except ZeroDivisionError:
                    w = 0
                w_data += [w]
        neighbors.update({str(i):n_data})
        weights.update({str(i):w_data})
    w = W(neighbors, weights, id_order = sorted(neighbors.keys()))
    for cluster in lq[list(lq.keys())[0]].keys():
        out = open("%s.local.dist.csv" % cluster, 'w')
        out.write("region, Q\n")
        for year in [ str(_) for _ in [2016] ]:
            data = []
            for region in lq.keys():
                try:
                    data += [lq[region][cluster][year]]
                except KeyError as e:
                    print(e)
                    data += [-1]
            data = np.array(data)
            mi = Moran_Local(data, w, permutations = 0, geoda_quads=1)
            Q = mi.q
            for i in range(len(regnames)):
                if Q[i] in [1,4]:
                    LQ = lq[regnames[i]][cluster]['2016']
                    out.write("%s,%s, %s\n" % (regnames[i], Q[i], LQ))
        out.close()
示例#7
0
def dist_weights(distfile, weight_type, ids, cutoff, inverse=False):
    """
    Returns a distance-based weights object using user-defined options
    
    Parameters
    ----------
    distfile: string, a path to distance csv file
    weighttype: string, either 'threshold' or 'knn'
    ids: a numpy array of id values
    cutoff: float or integer; float for 'threshold' weight type and integer for knn type
    inverse: boolean; true if inversed weights required

    """
    try:
        data_csv = csv.reader(open(distfile))
        if csv.Sniffer().has_header(distfile):
            next(data_csv)
    except:
        data_csv = None

    if weight_type == 'threshold':

        def neighbor_func(dists, threshold):
            dists = [x for x in dists if x[0] <= threshold]
            return dists
    else:

        def neighbor_func(dists, k):
            dists.sort()
            return dists[:k]

    if inverse:

        def weight_func(dists, alpha=-1.0):
            return list((np.array(dists)**alpha).round(decimals=6))
    else:

        def weight_func(dists, binary=False):
            return [1] * len(dists)

    dist_src = {}
    for row in data_csv:
        des = dist_src.setdefault(row[0], {})
        if row[0] != row[1]:
            des[row[1]] = float(row[2])

    neighbors, weights = {}, {}
    for id_val in ids:
        if id_val not in dist_src:
            raise ValueError('An ID value doest not exist in distance file')
        else:
            dists = list(
                zip(list(dist_src[id_val].values()),
                    list(dist_src[id_val].keys())))
        ngh, wgt = [], []
        if len(dists) > 0:
            nghs = neighbor_func(dists, cutoff)
            for d, i in nghs:
                ngh.append(i)
                wgt.append(d)
        neighbors[id_val] = ngh
        weights[id_val] = weight_func(wgt)
    w = W(neighbors, weights)
    w.id_order = ids
    return w
        if iID == jID:
            continue
        # 거리 계산
        dist = iCent.distance(jCent)
        if dist > NEIGHBOR_DIST:
            continue
        # weight 를 1로 부여
        iRowNeighbors.append(jID)
        iRowWeights.append(1)
    # iID 지역에 대한 인접 지역 및 가중치 기록
    if len(iRowNeighbors) > 0:
        neighbors[iID] = iRowNeighbors
        weights[iID] = iRowWeights
        yList.append(y)
# Weight Matrix 계산
w = W(neighbors, weights)
#w.transform = "B"

# Local Getis-Ord's G 계산
lg = G_Local(np.array(yList), w)

###########################
# 지도에 z 값을 기준으로 색으로 표현

# Create Result Layer
tLayerOption = "{0}?crs={1}&index=yes".format("Polygon", crs.authid())
tLayer = QgsVectorLayer(tLayerOption, "Getis_" + layerName, "memory")
tProvider = tLayer.dataProvider()
tLayer.startEditing()
tProvider.addAttributes([
    QgsField("id", QVariant.Int),