Esempio n. 1
0
def mkDfNodeAttribs(G):
    latCentroid, lngCentroid = utils.calcCentroidOfStops(G)

    ndAttribsVsR = []
    for node in G.nodes:
        lng = G.nodes[node][const.GNodeAttribs.Lng.name]
        lat = G.nodes[node][const.GNodeAttribs.Lat.name]
        ndAttribsVsR.append([
            node,
            utils.calcGeodesicDist([lng, lat], [lngCentroid, latCentroid]) /
            1000,  # in km
            lat,
            lng,
            G.nodes[node][const.GNodeAttribs.totDeg.name],
            G.nodes[node][const.GNodeAttribs.nLines.name],
            G.nodes[node][const.GNodeAttribs.nServices.name],
            G.nodes[node][const.GNodeAttribs.cbHops.name],
            G.nodes[node][const.GNodeAttribs.cbDist.name],
            G.nodes[node][const.GNodeAttribs.cbTime.name],
            G.nodes[node][const.GNodeAttribs.toV_u30.name],
            G.nodes[node][const.GNodeAttribs.frV_u30.name],
            G.nodes[node][const.GNodeAttribs.toV_3060.name],
            G.nodes[node][const.GNodeAttribs.frV_3060.name],
            G.nodes[node][const.GNodeAttribs.toV_6090.name],
            G.nodes[node][const.GNodeAttribs.frV_6090.name],
            G.nodes[node][const.GNodeAttribs.toV_o90.name],
            G.nodes[node][const.GNodeAttribs.frV_o90.name],
            G.nodes[node][const.GNodeAttribs.toV_u60.name],
            G.nodes[node][const.GNodeAttribs.frV_u60.name],
            G.nodes[node][const.GNodeAttribs.toV_u90.name],
            G.nodes[node][const.GNodeAttribs.frV_u90.name],
            G.nodes[node][const.GNodeAttribs.ndtoV_u30.name],
            G.nodes[node][const.GNodeAttribs.ndfrV_u30.name],
            G.nodes[node][const.GNodeAttribs.ndtoV_3060.name],
            G.nodes[node][const.GNodeAttribs.ndfrV_3060.name],
            G.nodes[node][const.GNodeAttribs.ndtoV_6090.name],
            G.nodes[node][const.GNodeAttribs.ndfrV_6090.name],
            G.nodes[node][const.GNodeAttribs.ndtoV_o90.name],
            G.nodes[node][const.GNodeAttribs.ndfrV_o90.name],
            G.nodes[node][const.GNodeAttribs.ndtoV_u60.name],
            G.nodes[node][const.GNodeAttribs.ndfrV_u60.name],
            G.nodes[node][const.GNodeAttribs.ndtoV_u90.name],
            G.nodes[node][const.GNodeAttribs.ndfrV_u90.name]
        ])
    df = pd.DataFrame(ndAttribsVsR,
                      columns=[
                          'StationId', 'R', 'Lat', 'Lng', 'totDeg', 'nLines',
                          'nServices', 'cbHops', 'cbDist', 'cbTime', 'toV_u30',
                          'frV_u30', 'toV_3060', 'frV_3060', 'toV_6090',
                          'frV_6090', 'toV_o90', 'frV_o90', 'toV_u60',
                          'frV_u60', 'toV_u90', 'frV_u90', 'ndtoV_u30',
                          'ndfrV_u30', 'ndtoV_3060', 'ndfrV_3060',
                          'ndtoV_6090', 'ndfrV_6090', 'ndtoV_o90', 'ndfrV_o90',
                          'ndtoV_u60', 'ndfrV_u60', 'ndtoV_u90', 'ndfrV_u90'
                      ])
    # df.to_csv('%s/nodeCentrals/proxDensVsR.csv' % const.outputsFolder, index=False)
    df['range'] = df['R'].apply(utils.getRange)
    return df
Esempio n. 2
0
def calcTargetClosenessCentrality(G, shortHops, shortDist, shortTime):
    '''
    calculates normalised closeness centralities by target from results of shortest distances
    - ignoring identical nodes
    - ignoring nodes within walk distance to each other
    Run of BUDF
    :param G:
    :param shortHops:
    :param shortDist:
    :param shortTime:
    :return:
    '''

    lenKey = 0
    pathKey = 1

    distTo = []
    for jNode in G.nodes():
        lenHops = 0
        lenDist = 0
        lenTime = 0
        for iNode in G.nodes():
            if iNode == jNode: continue

            nodeiCoord = [
                G.nodes[iNode][const.GNodeAttribs.Lng.name],
                G.nodes[iNode][const.GNodeAttribs.Lat.name]
            ]
            nodejCoord = [
                G.nodes[jNode][const.GNodeAttribs.Lng.name],
                G.nodes[jNode][const.GNodeAttribs.Lat.name]
            ]
            dist = utils.calcGeodesicDist(nodeiCoord,
                                          nodejCoord)  # distance in metres
            if dist <= const.maxWalkDist: continue

            lenHops += shortHops[iNode][lenKey][jNode]
            lenDist += shortDist[iNode][lenKey][jNode]
            lenTime += shortTime[iNode][lenKey][jNode]

        distTo.append([jNode, lenHops, lenDist, lenTime])

    dfDistTo = pd.DataFrame(distTo,
                            columns=['node', 'lenHops', 'lenDist', 'lenTime'])
    dfDistTo['lenHopsNorm'] = dfDistTo['lenHops'].apply(
        lambda x: len(G.nodes) / x)
    dfDistTo['lenDistNorm'] = dfDistTo['lenDist'].apply(
        lambda x: len(G.nodes) / x)
    dfDistTo['lenTimeNorm'] = dfDistTo['lenTime'].apply(
        lambda x: len(G.nodes) / x)

    return dfDistTo
Esempio n. 3
0
def calcNearbyNodes(G):
    for inode in G.nodes:
        nodeiCoord = [
            G.nodes[inode][const.GNodeAttribs.Lng.name],
            G.nodes[inode][const.GNodeAttribs.Lat.name]
        ]
        neighbours = []
        for jnode in G.nodes:
            if jnode == inode: continue
            nodejCoord = [
                G.nodes[jnode][const.GNodeAttribs.Lng.name],
                G.nodes[jnode][const.GNodeAttribs.Lat.name]
            ]
            dist = utils.calcGeodesicDist(nodeiCoord,
                                          nodejCoord)  # distance in metres
            if dist <= const.maxWalkDist:
                neighbours.append(jnode)
        G.nodes[inode][const.GNodeAttribs.neighbourNodes.name] = neighbours
Esempio n. 4
0
def calcBetweennessCentrality(G, shortHops, shortDist, shortTime):
    '''
    calculates betweenness centrality for all pair of nodes that are
    - not identical
    - not within walk distance to each other
    :param shortHops:
    :param shortDist:
    :param shortTime:
    :return:
    '''

    lenKey = 0
    pathKey = 1

    cb = []
    for node in G.nodes:
        ndCbHops = 0
        ndCbDist = 0
        ndCbTime = 0
        for iNode in G.nodes:
            if iNode == node: continue
            for jNode in G.nodes():
                if jNode == node or jNode == iNode: continue

                nodeiCoord = [
                    G.nodes[iNode][const.GNodeAttribs.Lng.name],
                    G.nodes[iNode][const.GNodeAttribs.Lat.name]
                ]
                nodejCoord = [
                    G.nodes[jNode][const.GNodeAttribs.Lng.name],
                    G.nodes[jNode][const.GNodeAttribs.Lat.name]
                ]
                dist = utils.calcGeodesicDist(nodeiCoord,
                                              nodejCoord)  # distance in metres
                if dist <= const.maxWalkDist: continue

                sPathHops = shortHops[iNode][pathKey][jNode]
                sPathDist = shortDist[iNode][pathKey][jNode]
                sPathTime = shortTime[iNode][pathKey][jNode]
                if node in sPathHops:
                    ndCbHops += 1
                if node in sPathDist:
                    ndCbDist += 1
                if node in sPathTime:
                    ndCbTime += 1

        cb.append([node, ndCbHops, ndCbDist, ndCbTime])

    dfCb = pd.DataFrame(cb, columns=['node', 'cbHops', 'cbDist', 'cbTime'])
    cbHopsMax = dfCb['CbHops'].max()
    cbHopsMin = dfCb['CbHops'].min()
    cbDistMax = dfCb['CbDist'].max()
    cbDistMin = dfCb['CbDist'].min()
    cbTimeMax = dfCb['CbTime'].max()
    cbTimeMin = dfCb['CbTime'].min()

    dfCb['cbHopsNorm'] = dfCb.apply(lambda row: (row['CbHops'] - cbHopsMin) /
                                    (cbHopsMax - cbHopsMin),
                                    axis=1)
    dfCb['cbDistNorm'] = dfCb.apply(lambda row: (row['CbDist'] - cbDistMin) /
                                    (cbDistMax - cbDistMin),
                                    axis=1)
    dfCb['cbTimeNorm'] = dfCb.apply(lambda row: (row['CbTime'] - cbTimeMin) /
                                    (cbTimeMax - cbTimeMin),
                                    axis=1)

    return dfCb
Esempio n. 5
0
def calcShortestPaths_v2(G, dfRoutes, edgeWeight=None):
    '''
    calculate shortest path between all node pairs in G, except for:
    - two identical nodes
    - two nodes within 300m of each other and not directly connected.
    - two nodes on the same directed route
    :param G:
    :param edgeWeight:
    :return:
    '''
    shortestPaths = {}
    for nodei in G.nodes():
        shortestPaths[nodei] = {}
        for nodej in G.nodes():
            # IF THE 2 NODES ARE IDENTICAL
            if nodej==nodei:
                continue

            # IF THERE'S A DIRECT LINK BETWEEN THEM
            if G.has_edge(nodei, nodej):
                shortestPaths[nodei][nodej] = {}
                shortestPaths[nodei][nodej]['path'] = [nodei, nodej]
                shortestPaths[nodei][nodej]['len'] = calcPathLength(G, [nodei, nodej], edgeWeight)
                continue

            # IF THEY ARE ON THE SAME DIRECTED ROUTE (AND nodei IS BEFORE nodej)
            # combines routeID_StationDirection (e.g. 25_0) of all directed routes passing nodei and passing nodej
            # rNdi and rNdj are pandas Series
            rNdi = G.nodes[nodei][const.GNodeAttribs.routes.name].apply(
                lambda row: '%d_%d' % (row[const.GNodeRouteCols.RouteId.name],
                                       row[const.GNodeRouteCols.StationDirection.name]), axis=1)
            rNdj = G.nodes[nodej][const.GNodeAttribs.routes.name].apply(
                lambda row: '%d_%d' % (row[const.GNodeRouteCols.RouteId.name],
                                       row[const.GNodeRouteCols.StationDirection.name]), axis=1)
            # if found at least one common directed route, i.e. nodei and nodej are on the same directed route
            commonRoutes = list(set(rNdi.values).intersection(set(rNdj.values)))
            # reverse engineer to get routeID and StationDirection using the 1st value in commonRoutes
            # ideally we should examine all routes in commonRoutes and pick the shortest.
            # However picking the 1st route that have nodei before nodej should be fine 95% of the time.
            # Note that it is possible that we may not find any such route in commonRoutes
            onSameRoute = False
            for route in commonRoutes:
                routeID = int(route.split('_')[0])
                stnDir = int(route.split('_')[1])
                ttb = dfRoutes['designedTtb'].loc[(dfRoutes['RouteId'] == routeID) &
                                                  (dfRoutes['StationDirection'] == stnDir)].values[0]
                idxNodei = ttb['StationCode'].index(nodei)
                idxNodej = ttb['StationCode'].index(nodej)
                if idxNodei < idxNodej:
                    onSameRoute = True
                    sPath = ttb['StationCode'][idxNodei:idxNodej+1]
                    shortestPaths[nodei][nodej] = {}
                    shortestPaths[nodei][nodej]['path'] = sPath
                    shortestPaths[nodei][nodej]['len'] = calcPathLength(G, sPath, edgeWeight)
                    break
            if onSameRoute:
                continue

            # IF 2 NODES ARE WITHIN WALK DISTANCE TO EACH OTHER AND ARE NOT ON THE SAME DIRECTED ROUTE
            nodeiCoord = [G.nodes[nodei][const.GNodeAttribs.Lng.name], G.nodes[nodei][const.GNodeAttribs.Lat.name]]
            nodejCoord = [G.nodes[nodej][const.GNodeAttribs.Lng.name], G.nodes[nodej][const.GNodeAttribs.Lat.name]]
            dist = utils.calcGeodesicDist(nodeiCoord, nodejCoord)  # distance in metres
            if dist <= const.maxWalkDist:
                continue

            # NONE OF THE ABOVE
            sPath = nx.shortest_path(G, source=nodei, target=nodej, weight=edgeWeight, method='dijkstra') # method='bellman-ford'
            shortestPaths[nodei][nodej] = {}
            shortestPaths[nodei][nodej]['path'] = sPath
            shortestPaths[nodei][nodej]['len'] = calcPathLength(G, sPath, edgeWeight)

    return shortestPaths