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
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
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)
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()
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()
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),