Access Class API

class access.Access(demand_df, demand_value, supply_df, supply_value=False, demand_index=True, supply_index=True, cost_df=None, cost_origin=None, cost_dest=None, cost_name=None, neighbor_cost_df=None, neighbor_cost_origin=None, neighbor_cost_dest=None, neighbor_cost_name=None)[source]

Spatial Access Class

Parameters:
demand_dfpandas.DataFrame or geopandas.GeoDataFrame

The origins dataframe, containing a location index and, optionally, a level of demand and geometry.

demand_index{bool, str}

boolean of True indicates that the locations are already on the df index; otherwise the argument is a string containing the name of the column of demand_df that holds the origin ID.

demand_valuestr

is the name of the column of demand that holds the aggregate demand at a location.

supply_dfpandas.DataFrame or geopandas.GeoDataFrame

The origins dataframe, containing a location index and, optionally, level of supply and geometry.

supply_index{bool, str}

boolean of True indicates that the locations are already on the df index; otherwise the argument is a string containing the name of the column of supply_df that holds the origin ID.

supply_value{str, list}

is the name of the column of supply that holds the aggregate supply at a location, or a list of such columns.

cost_dfpandas.DataFrame

This dataframe contains a link from demand to supply locations, and a cost between them.

cost_originstr

The column name of the index locations – this is what will be grouped by.

cost_deststr

The column name of the neighborhing demand locations – this is what goes in the groups.

cost_name{str, list}

The column(s) name of the travel cost(s).

neighbor_cost_dfpandas.DataFrame

This dataframe contains a link from demand to neighbor locations, and a cost between them (running consumer to supplier).

neighbor_cost_originstr

The column name of the origin locations – this is what will be grouped by.

neighbor_cost_deststr

The column name of the destination locations – this is what goes in the groups.

neighbor_cost_name{str, list}

The column name(s) of the travel cost(s).

Attributes:
Accesspandas.DataFrame

All of the calculated access measures.

access_metadatapandas.DataFrame

Lists currently-available measures of access.

cost_metadatapandas.DataFrame

Describes each of the currently-available supply to demand costs.

Methods

append_user_cost(new_cost_df, origin, ...)

Create a user cost, from demand to supply locations.

append_user_cost_neighbors(new_cost_df, ...)

Create a user cost, from supply locations to other supply locations.

create_euclidean_distance([name, threshold, ...])

Calculate the Euclidean distance from demand to supply locations.

create_euclidean_distance_neighbors([name, ...])

Calculate the Euclidean distance among demand locations.

enhanced_two_stage_fca([name, cost, ...])

Calculate the enhanced two-stage floating catchment area access score.

fca_ratio([name, demand_cost, supply_cost, ...])

Calculate the floating catchment area (buffer) ratio access score.

raam([name, cost, supply_values, normalize, ...])

Calculate the rational agent access model.

score(col_dict[, name])

Weighted aggregate of multiple already-calculated, normalized access components.

three_stage_fca([name, cost, supply_values, ...])

Calculate the three-stage floating catchment area access score.

two_stage_fca([name, cost, max_cost, ...])

Calculate the two-stage floating catchment area access score.

weighted_catchment([name, supply_cost, ...])

Calculate the catchment area (buffer) aggregate access score.

__init__(demand_df, demand_value, supply_df, supply_value=False, demand_index=True, supply_index=True, cost_df=None, cost_origin=None, cost_dest=None, cost_name=None, neighbor_cost_df=None, neighbor_cost_origin=None, neighbor_cost_dest=None, neighbor_cost_name=None)[source]

Initialize the class.

Examples

Import the base Access class and Datasets.

>>> from access import Access, Datasets

Load each of the example datasets:

>>> chi_docs_dents   = Datasets.load_data('chi_doc')
>>> chi_population   = Datasets.load_data('chi_pop')
>>> chi_travel_costs = Datasets.load_data('chi_times')
>>> chi_docs_dents.head()
         geoid  doc  dentist
0  17031010100    1        1
1  17031010201    0        1
2  17031010202    4        1
3  17031010300    4        1
4  17031010400    0        2
>>> chi_population.head()
         geoid   pop
0  17031010100  4854
1  17031010201  6450
2  17031010202  2818
3  17031010300  6236
4  17031010400  5042
>>> chi_travel_costs.head()
        origin         dest   cost
0  17093890101  17031010100  91.20
1  17093890101  17031010201  92.82
2  17093890101  17031010202  92.95
3  17093890101  17031010300  89.40
4  17093890101  17031010400  84.97

Using the example data, create an Access object.

>>> chicago_primary_care = Access(demand_df = chi_population, demand_index = "geoid",
                                  demand_value = "pop",
                                  supply_df = chi_docs_dents, supply_index = "geoid",
                                  supply_value = ["doc", "dentist"],
                                  cost_df = chi_travel_costs, cost_origin  = "origin",
                                  cost_dest = "destination", cost_name = "cost")
append_user_cost(new_cost_df, origin, destination, name)[source]

Create a user cost, from demand to supply locations.

Parameters:
new_cost_dfpandas.DataFrame

Holds the new cost….

namestr

Name of the new cost variable in new_cost_df

originstr

Name of the new origin variable in new_cost_df

destinationstr

Name of the new destination variable in new_cost_df

Examples

Import the base Access class and Datasets.

>>> from access import Access, Datasets

Load each of the example datasets:

>>> chi_docs_dents   = Datasets.load_data('chi_doc')
>>> chi_population   = Datasets.load_data('chi_pop')
>>> chi_travel_costs = Datasets.load_data('chi_times')
>>> chi_docs_dents.head()
         geoid  doc  dentist
0  17031010100    1        1
1  17031010201    0        1
2  17031010202    4        1
3  17031010300    4        1
4  17031010400    0        2
>>> chi_population.head()
         geoid   pop
0  17031010100  4854
1  17031010201  6450
2  17031010202  2818
3  17031010300  6236
4  17031010400  5042
>>> chi_travel_costs.head()
        origin         dest   cost
0  17093890101  17031010100  91.20
1  17093890101  17031010201  92.82
2  17093890101  17031010202  92.95
3  17093890101  17031010300  89.40
4  17093890101  17031010400  84.97

Using the example data, create an Access object.

>>> chicago_primary_care = Access(demand_df = chi_population, demand_index = "geoid",
                                  demand_value = "pop",
                                  supply_df = chi_docs_dents, supply_index = "geoid",
                                  supply_value = ["doc", "dentist"],
                                  cost_df = chi_travel_costs, cost_origin  = "origin",
                                  cost_dest = "destination", cost_name = "cost")

To add a new cost from demand to supply locations, first load the new cost data.

>>> euclidean_cost = Datasets.load_data('chi_euclidean')
    euclidean_cost.head()
        origin         dest     euclidean
0  17093890101  17031010100  63630.788476
1  17093890101  17031010201  62632.675522
2  17093890101  17031010202  63073.735631
3  17093890101  17031010300  63520.029749
4  17093890101  17031010400  63268.514352

Add new cost data to existing Access instance.

>>> chicago_primary_care.append_user_cost(new_cost_df = euclidean_cost,
                                   name = "euclidean",
                                   origin = "origin",
                                   destination = "dest")

The newly added cost data can be seen in the cost_df attribute.

>>> chicago_primary_care.cost_df.head()
        origin         dest   cost     euclidean
0  17093890101  17031010100  91.20  63630.788476
1  17093890101  17031010201  92.82  62632.675522
2  17093890101  17031010202  92.95  63073.735631
3  17093890101  17031010300  89.40  63520.029749
4  17093890101  17031010400  84.97  63268.514352
append_user_cost_neighbors(new_cost_df, origin, destination, name)[source]

Create a user cost, from supply locations to other supply locations.

Parameters:
new_cost_dfpandas.DataFrame

Holds the new cost….

coststr

Name of the new cost variable in new_cost_df

originstr

Name of the new origin variable in new_cost_df

destinationstr

Name of the new destination variable in new_cost_df

Examples

Import the base Access class and Datasets.

>>> from access import Access, Datasets

Load each of the example datasets:

>>> chi_docs_dents   = Datasets.load_data('chi_doc')
>>> chi_population   = Datasets.load_data('chi_pop')
>>> chi_travel_costs = Datasets.load_data('chi_times')
>>> chi_docs_dents.head()
         geoid  doc  dentist
0  17031010100    1        1
1  17031010201    0        1
2  17031010202    4        1
3  17031010300    4        1
4  17031010400    0        2
>>> chi_population.head()
         geoid   pop
0  17031010100  4854
1  17031010201  6450
2  17031010202  2818
3  17031010300  6236
4  17031010400  5042
>>> chi_travel_costs.head()
        origin         dest   cost
0  17093890101  17031010100  91.20
1  17093890101  17031010201  92.82
2  17093890101  17031010202  92.95
3  17093890101  17031010300  89.40
4  17093890101  17031010400  84.97

Using the example data, create an Access object.

>>> chicago_primary_care = Access(demand_df = chi_population, demand_index = "geoid",
                                  demand_value = "pop",
                                  supply_df = chi_docs_dents, supply_index = "geoid",
                                  supply_value = ["doc", "dentist"],
                                  cost_df = chi_travel_costs, cost_origin  = "origin",
                                  cost_dest = "destination", cost_name = "cost")

To add a new cost from demand to supply locations, first load the new cost data.

>>> euclidean_cost_neighbors = Datasets.load_data('chi_euclidean_neighbors')
    euclidean_cost_neighbors.head()
        origin         dest  euclidean_neighbors
0  17031010100  17031010100             0.000000
1  17031010100  17031010201           998.259243
2  17031010100  17031010202           635.203387
3  17031010100  17031010300           653.415713
4  17031010100  17031010400          2065.375554

Add new cost data to existing Access instance.

>>> chicago_primary_care.append_user_cost_neighbors(new_cost_df = euclidean_cost_neighbors,
                                             name = "euclidean_neighbors",
                                             origin = "origin",
                                             destination = "dest")

The newly added cost data can be seen in the neighbor_cost_df attribute.

>>> chicago_primary_care.neighbor_cost_df.head()
        origin         dest   cost   euclidean_neighbors
0  17093890101  17031010100  91.20          63630.788476
1  17093890101  17031010201  92.82          62632.675522
2  17093890101  17031010202  92.95          63073.735631
3  17093890101  17031010300  89.40          63520.029749
4  17093890101  17031010400  84.97          63268.514352
create_euclidean_distance(name='euclidean', threshold=0, centroid_o=False, centroid_d=False)[source]

Calculate the Euclidean distance from demand to supply locations. This is simply the geopandas distance function. The user is responsible for putting the geometries into an appropriate reference system.

Parameters:
namestr

Column name for euclidean distances

thresholdint

Buffer threshold for non-point geometries, AKA max_distance

centroid_obool

If True, convert geometries of demand_df (origins) to centroids; otherwise, no change

centroid_dbool

If True, convert geometries of supply_df (destinations) to centroids; otherwise, no change

Examples

NOTE: Creating euclidean distance measures requires having a geometry column in a geopandas.GeoDataFrame.

Import the base Access class and Datasets.

>>> from access import Access, Datasets

Load each of the example datasets which correspond to the demand (population), supply (doctors and dentists) and cost (travel time), respectively. The sample data represents the Chicago metro area with a 50km buffer around the city boundaries.

>>> chi_docs_dents   = Datasets.load_data('chi_doc_geom')
>>> chi_population   = Datasets.load_data('chi_pop_geom')
>>> chi_travel_costs = Datasets.load_data('chi_times')
>>> chi_docs_dents.head()
             doc  dentist                       geometry
geoid
17031010100    1        1  POINT (354916.992 594670.505)
17031010201    0        1  POINT (354105.876 594088.600)
17031010202    4        1  POINT (354650.684 594093.822)
17031010300    4        1  POINT (355209.361 594086.149)
17031010400    0        2  POINT (355809.748 592808.043)
>>> chi_population.head()
              pop                       geometry
geoid
17031010100  4854  POINT (354916.992 594670.505)
17031010201  6450  POINT (354105.876 594088.600)
17031010202  2818  POINT (354650.684 594093.822)
17031010300  6236  POINT (355209.361 594086.149)
17031010400  5042  POINT (355809.748 592808.043)

The chi_travel_costs dataset is the cost matrix, showing the travel time between each of the Census Tracts in the Chicago metro area.

>>> chi_travel_costs.head()
        origin         dest   cost
0  17093890101  17031010100  91.20
1  17093890101  17031010201  92.82
2  17093890101  17031010202  92.95
3  17093890101  17031010300  89.40
4  17093890101  17031010400  84.97

Now, create an instance of the Access class and specify the demand, supply, and cost datasets.

>>> chicago_primary_care = Access(demand_df = chi_population, demand_index = "geoid",
                                  demand_value = "pop",
                                  supply_df = chi_docs_dents, supply_index = "geoid",
                                  supply_value = ["doc", "dentist"],
                                  cost_df = chi_travel_costs, cost_origin  = "origin",
                                  cost_dest = "dest", cost_name = "cost")

To calculate euclidean distances between Census Tracts within 250km of eachother, you can set the threshold to 250000 (meters). Setting centroid_o and centroid_d to True calculates the centroid of the geom in your dataset.

>>> chicago_primary_care.create_euclidean_distance(threshold = 250000, centroid_o = True, centroid_d = True)

The newly calculated euclidean costs are added to the cost_df attribute of the Access class.

>>> chicago_primary_care_geom.cost_df.head()
        origin         dest   cost     euclidean
0  17093890101  17031010100  91.20  63630.788476
1  17093890101  17031010201  92.82  62632.675522
2  17093890101  17031010202  92.95  63073.735631
3  17093890101  17031010300  89.40  63520.029749
4  17093890101  17031010400  84.97  63268.514352
create_euclidean_distance_neighbors(name='euclidean', threshold=0, centroid=False)[source]

Calculate the Euclidean distance among demand locations.

Parameters:
namestr

Column name for euclidean distances neighbors

thresholdint

Buffer threshold for non-point geometries, AKA max_distance

centroidbool

If True, convert geometries to centroids; otherwise, no change

Examples

NOTE: Creating euclidean distance measures requires having a geometry column in a geopandas.GeoDataFrame.

Import the base Access class and Datasets.

>>> from access import Access, Datasets

Load each of the example datasets which correspond to the demand (population), supply (doctors and dentists) and cost (travel time), respectively. The sample data represents the Chicago metro area with a 50km buffer around the city boundaries.

>>> chi_docs_dents   = Datasets.load_data('chi_doc_geom')
>>> chi_population   = Datasets.load_data('chi_pop_geom')
>>> chi_travel_costs = Datasets.load_data('chi_times')
>>> chi_docs_dents.head()
             doc  dentist                       geometry
geoid
17031010100    1        1  POINT (354916.992 594670.505)
17031010201    0        1  POINT (354105.876 594088.600)
17031010202    4        1  POINT (354650.684 594093.822)
17031010300    4        1  POINT (355209.361 594086.149)
17031010400    0        2  POINT (355809.748 592808.043)
>>> chi_population.head()
              pop                       geometry
geoid
17031010100  4854  POINT (354916.992 594670.505)
17031010201  6450  POINT (354105.876 594088.600)
17031010202  2818  POINT (354650.684 594093.822)
17031010300  6236  POINT (355209.361 594086.149)
17031010400  5042  POINT (355809.748 592808.043)

The chi_travel_costs dataset is the cost matrix, showing the travel time between each of the Census Tracts in the Chicago metro area.

>>> chi_travel_costs.head()
        origin         dest   cost
0  17093890101  17031010100  91.20
1  17093890101  17031010201  92.82
2  17093890101  17031010202  92.95
3  17093890101  17031010300  89.40
4  17093890101  17031010400  84.97

Make sure you assign your desired geometry projection, which you can change as follows.

>>> chi_population = chi_population.to_crs(epsg = 2790)
>>> chi_docs_dents = chi_docs_dents.to_crs(epsg = 2790)

Now, create an instance of the Access class and specify the demand, supply, and cost datasets.

>>> chicago_primary_care = Access(demand_df = chi_population, demand_index = "geoid",
                                  demand_value = "pop",
                                  supply_df = chi_docs_dents, supply_index = "geoid",
                                  supply_value = ["doc", "dentist"],
                                  cost_df = chi_travel_costs, cost_origin  = "origin",
                                  cost_dest = "dest", cost_name = "cost")

To calculate euclidean distances between Census Tracts within 250km of eachother, you can set the threshold to 250000 (meters). Setting centroid_o and centroid_d to True calculates the centroid of the geom in your dataset.

>>> chicago_primary_care.create_euclidean_distance_neighbors(name= 'euclidean_neighbors', threshold = 250000, centroid_o = True, centroid_d = True)

The newly calculated euclidean distance is stored in the neighbor_cost_df attribute.

>>> chicago_primary_care_geom.neighbor_cost_df.head()
        origin         dest  euclidean_neighbors
0  17031010100  17031010100             0.000000
1  17031010100  17031010201           998.259243
2  17031010100  17031010202           635.203387
3  17031010100  17031010300           653.415713
4  17031010100  17031010400          2065.375554
enhanced_two_stage_fca(name='e2sfca', cost=None, supply_values=None, max_cost=None, weight_fn=None, normalize=False)[source]

Calculate the enhanced two-stage floating catchment area access score. Note that the only ‘practical’ difference between this function and the Access.access.two_stage_fca() is that the weight function from the original paper, weights.step_fn({10 : 1, 20 : 0.68, 30 : 0.22}) is applied if none is provided.

Parameters:
namestr

Column name for access values

coststr

Name of cost value column in cost_df (supply-side)

max_costfloat

Cutoff of cost values

supply_values{str, list}

supply type or types.

weight_fnfunction

Weight to be applied to access values

normalizebool

If True, return normalized access values; otherwise, return raw access values

Returns:
accesspandas Series

Accessibility score for origin locations.

Examples

Import the base Access class and Datasets.

>>> from access import Access, Datasets

Load each of the example datasets:

>>> chi_docs_dents   = Datasets.load_data('chi_doc')
>>> chi_population   = Datasets.load_data('chi_pop')
>>> chi_travel_costs = Datasets.load_data('chi_times')
>>> chi_docs_dents.head()
         geoid  doc  dentist
0  17031010100    1        1
1  17031010201    0        1
2  17031010202    4        1
3  17031010300    4        1
4  17031010400    0        2
>>> chi_population.head()
         geoid   pop
0  17031010100  4854
1  17031010201  6450
2  17031010202  2818
3  17031010300  6236
4  17031010400  5042
>>> chi_travel_costs.head()
        origin         dest   cost
0  17093890101  17031010100  91.20
1  17093890101  17031010201  92.82
2  17093890101  17031010202  92.95
3  17093890101  17031010300  89.40
4  17093890101  17031010400  84.97

Using the example data, create an Access object.

>>> chicago_primary_care = Access(demand_df = chi_population, demand_index = "geoid",
                                  demand_value = "pop",
                                  supply_df = chi_docs_dents, supply_index = "geoid",
                                  supply_value = ["doc", "dentist"],
                                  cost_df = chi_travel_costs, cost_origin  = "origin",
                                  cost_dest = "destination", cost_name = "cost")

We can create multiple stepwise functions for weights.

>>> fn30 = weights.step_fn({10 : 1, 20 : 0.68, 30 : 0.22})
>>> fn60 = weights.step_fn({20 : 1, 40 : 0.68, 60 : 0.22})

Using those two difference stepwise functions, we can create two separate enhanced two stage fca measures.

>>> chicago_primary_care.enhanced_two_stage_fca(name = '2sfca30', weight_fn = fn30)
             2sfca30_doc  2sfca30_dentist
geoid
17031010100     0.000970         0.000461
17031010201     0.001080         0.000557
17031010202     0.001027         0.000531
...........     ........         ........
17197884101     0.000159         0.000241
17197884103     0.000285         0.000342
17197980100     0.000266         0.000310

Note the use of the name argument in order to specify a different column name prefix for the access measure.

>>> chicago_primary_care.enhanced_two_stage_fca(name = '2sfca60', weight_fn = fn60)
             2sfca60_doc  2sfca60_dentist
geoid
17031010100     0.000687         0.000394
17031010201     0.000750         0.000447
17031010202     0.000720         0.000416
...........     ........         ........
17197884101     0.000392         0.000301
17197884103     0.000289         0.000243
17197980100     0.000333         0.000268

Both newly created enhanced two stage fca measures are stored in the access_df attribute of the Access object.

>>> chicago_primary_care.access_df.head()
              pop  2sfca30_doc  2sfca30_dentist  2sfca60_doc  2sfca60_dentist
geoid
17031010100  4854     0.000970         0.000461     0.000687         0.000394
17031010201  6450     0.001080         0.000557     0.000750         0.000447
17031010202  2818     0.001027         0.000531     0.000720         0.000416
17031010300  6236     0.001030         0.000496     0.000710         0.000402
17031010400  5042     0.000900         0.000514     0.000786         0.000430
fca_ratio(name='fca', demand_cost=None, supply_cost=None, supply_values=None, max_cost=None, normalize=False, noise='quiet')[source]

Calculate the floating catchment area (buffer) ratio access score.

Parameters:
namestr

Column name for access values

demand_coststr

Name of demand cost value column in demand_df

supply_coststr

Name of supply cost value column in supply_df

supply_values{str, list}

Name(s) of supply values in supply_df

max_costfloat

Cutoff of cost values

normalizebool

If True, return normalized access values; otherwise, return raw access values

noisestr

Default ‘quiet’, otherwise gives messages that indicate potential issues.

Returns:
accesspandas Series

Accessibility score for origin locations.

Examples

Import the base Access class and Datasets.

>>> from access import Access, Datasets

Load each of the example datasets:

>>> chi_docs_dents   = Datasets.load_data('chi_doc')
>>> chi_population   = Datasets.load_data('chi_pop')
>>> chi_travel_costs = Datasets.load_data('chi_times')
>>> chi_docs_dents.head()
         geoid  doc  dentist
0  17031010100    1        1
1  17031010201    0        1
2  17031010202    4        1
3  17031010300    4        1
4  17031010400    0        2
>>> chi_population.head()
         geoid   pop
0  17031010100  4854
1  17031010201  6450
2  17031010202  2818
3  17031010300  6236
4  17031010400  5042
>>> chi_travel_costs.head()
        origin         dest   cost
0  17093890101  17031010100  91.20
1  17093890101  17031010201  92.82
2  17093890101  17031010202  92.95
3  17093890101  17031010300  89.40
4  17093890101  17031010400  84.97

Using the example data, create an Access object.

>>> chicago_primary_care = Access(demand_df = chi_population, demand_index = "geoid",
                                  demand_value = "pop",
                                  supply_df = chi_docs_dents, supply_index = "geoid",
                                  supply_value = ["doc", "dentist"],
                                  cost_df = chi_travel_costs, cost_origin  = "origin",
                                  cost_dest = "destination", cost_name = "cost",
                                  neighbor_cost_df = chi_travel_costs, neighbor_cost_origin = "origin",
                                  neighbor_cost_dest = 'dest', neighbor_cost_name = 'cost')
>>> chicago_primary_care.fca_ratio(name='fca',max_cost=30)
              fca_doc  fca_dentist
geoid
17031010100  0.001630     0.000807
17031010201  0.001524     0.000904
17031010202  0.001521     0.000908
...........  ........     ........
17197884101  0.000437     0.000442
17197884103  0.000510     0.000498
17197980100  0.000488     0.000432
raam(name='raam', cost=None, supply_values=None, normalize=False, tau=60, rho=None, max_cycles=150, initial_step=0.2, half_life=50, min_step=0.005, verbose=False)[source]

Calculate the rational agent access model. [Saxon and Snow, 2019]

Parameters:
namestr

Column name for access values

coststr

Name of cost variable, for reaching supply sites.

supply_values{str, list}

Name(s) of supply values in supply_df

normalizebool

If True, return normalized access values; otherwise, return raw access values

taufloat

tau parameter (travel time scale)

rhofloat

rho parameter (congestion cost scale)

max_cyclesint

How many cycles to run the RAAM optimization for.

initial_step{int, float}

If an float < 1, it is the proportion of a demand site that can shift, in the first cycle. If it is an integer, it is simply a limit on the total number.

half_lifeint

How many cycles does it take to halve the move rate?

min_step{int, float}

This is the minimum value, to which the moving fraction converges.

verbosebool

Print some information as the optimization proceeds.

Returns:
accesspandas Series

Accessibility score for origin locations.

Examples

Import the base Access class and Datasets.

>>> from access import Access, Datasets

Load each of the example datasets which correspond to the demand (population), supply (doctors and dentists) and cost (travel time), respectively. The sample data represents the Chicago metro area with a 50km buffer around the city boundaries.

>>> chi_docs_dents   = Datasets.load_data('chi_doc')
>>> chi_population   = Datasets.load_data('chi_pop')
>>> chi_travel_costs = Datasets.load_data('chi_times')
>>> chi_docs_dents.head()
         geoid  doc  dentist
0  17031010100    1        1
1  17031010201    0        1
2  17031010202    4        1
3  17031010300    4        1
4  17031010400    0        2
>>> chi_population.head()
         geoid   pop
0  17031010100  4854
1  17031010201  6450
2  17031010202  2818
3  17031010300  6236
4  17031010400  5042

The chi_travel_costs dataset is the cost matrix, showing the travel time between each of the Census Tracts in the Chicago metro area.

>>> chi_travel_costs.head()
        origin         dest   cost
0  17093890101  17031010100  91.20
1  17093890101  17031010201  92.82
2  17093890101  17031010202  92.95
3  17093890101  17031010300  89.40
4  17093890101  17031010400  84.97

Now, create an instance of the Access class and specify the demand, supply, and cost datasets.

>>> chicago_primary_care = Access(demand_df = chi_population, demand_index = "geoid",
                                  demand_value = "pop",
                                  supply_df = chi_docs_dents, supply_index = "geoid",
                                  supply_value = ["doc", "dentist"],
                                  cost_df = chi_travel_costs, cost_origin  = "origin",
                                  cost_dest = "dest", cost_name = "cost")

With the demand, supply, and cost data provided, we can now produce the RAAM access measures defining a floating catchment area of 30 minutes by setting the tau value to 30 (60 minutes is the default).

>>> chicago_primary_care.raam(tau = 30)
             raam_doc  raam_dentist
geoid
17031010100  1.027597      1.137901
17031010201  0.940239      1.332557
17031010202  1.031144      1.413279
...........  ........      ........
17197884101  2.365171      1.758800
17197884103  2.244007      1.709857
17197980100  2.225820      1.778264

You can access the results stored in the Access.access_df attribute.

>>> chicago_primary_care.access_df
              pop  raam_doc  raam_dentist
geoid
17031010100  4854  1.027597      1.137901
17031010201  6450  0.940239      1.332557
17031010202  2818  1.031144      1.413279
...........   ....  ........      ........
17197884101  4166  2.365171      1.758800
17197884103  2776  2.244007      1.709857
17197980100  3264  2.225820      1.778264

By providing a string to the name argument, you can call the Access.raam method again using a different parameter of tau and save the outputs without overwriting previous ones.

>>> chicago_primary_care.raam(name = "raam2", tau = 2)
>>> chicago_primary_care.access_df
              pop  raam_doc  raam_dentist  raam45_doc  raam45_dentist
geoid
17031010100  4854  1.027597      1.137901    0.967900        1.075116
17031010201  6450  0.940239      1.332557    0.908518        1.133207
17031010202  2818  1.031144      1.413279    0.962915        1.206775
...........   ....  ........      ........   ........       ........
17197884101  4166  2.365171      1.758800    1.921161        1.495642
17197884103  2776  2.244007      1.709857    1.900596        1.517022
17197980100  3264  2.225820      1.778264    1.868281        1.582177

If euclidean costs are available (see Access.access.create_euclidean_distance()), you can use euclidean distance instead of time to calculate RAAM access measures. Insted of being measured in minutes, tau would now be measured in meters.

>>> chicago_primary_care.raam(name = "raam_euclidean", tau = 100, cost = "euclidean")
score(col_dict, name='score')[source]

Weighted aggregate of multiple already-calculated, normalized access components.

Parameters:
namestr

Column name for access values

col_dictdict

Column names (keys) and weights.

Returns:
accesspandas Series

Single, aggregate score for origin locations.

Examples

Import the base Access class and Datasets.

>>> from access import Access, Datasets

Load each of the example datasets which correspond to the demand (population), supply (doctors and dentists) and cost (travel time), respectively. The sample data represents the Chicago metro area with a 50km buffer around the city boundaries.

>>> chi_docs_dents   = Datasets.load_data('chi_doc')
>>> chi_population   = Datasets.load_data('chi_pop')
>>> chi_travel_costs = Datasets.load_data('chi_times')
>>> chi_docs_dents.head()
         geoid  doc  dentist
0  17031010100    1        1
1  17031010201    0        1
2  17031010202    4        1
3  17031010300    4        1
4  17031010400    0        2
>>> chi_population.head()
         geoid   pop
0  17031010100  4854
1  17031010201  6450
2  17031010202  2818
3  17031010300  6236
4  17031010400  5042

The chi_travel_costs dataset is the cost matrix, showing the travel time between each of the Census Tracts in the Chicago metro area.

>>> chi_travel_costs.head()
        origin         dest   cost
0  17093890101  17031010100  91.20
1  17093890101  17031010201  92.82
2  17093890101  17031010202  92.95
3  17093890101  17031010300  89.40
4  17093890101  17031010400  84.97

Now, create an instance of the Access class and specify the demand, supply, and cost datasets.

>>> chicago_primary_care = Access(demand_df = chi_population, demand_index = "geoid",
                                  demand_value = "pop",
                                  supply_df = chi_docs_dents, supply_index = "geoid",
                                  supply_value = ["doc", "dentist"],
                                  cost_df = chi_travel_costs, cost_origin  = "origin",
                                  cost_dest = "dest", cost_name = "cost")

With the demand, supply, and cost data provided, we can now produce the RAAM access measures defining a floating catchment area of 30 minutes by setting the tau value to 30 (60 minutes is the default).

>>> chicago_primary_care.raam(tau = 30)
             raam_doc  raam_dentist
geoid
17031010100  1.027597      1.137901
17031010201  0.940239      1.332557
17031010202  1.031144      1.413279
...........  ........      ........
17197884101  2.365171      1.758800
17197884103  2.244007      1.709857
17197980100  2.225820      1.778264

Aggregate RAAM for doctors and dentists, weighting doctors more heavily.

>>> chicago_primary_care.score(name = "raam_combo", col_dict = {"raam_doc" : 0.8, "raam_dentist" : 0.2})
geoid
17031010100    0.786697
17031010201    0.765081
17031010202    0.831578
...........    ........
17197884101    1.677075
17197884103    1.597554
17197980100    1.597386
three_stage_fca(name='3sfca', cost=None, supply_values=None, max_cost=None, weight_fn=None, normalize=False)[source]

Calculate the three-stage floating catchment area access score.

Parameters:
namestr

Column name for access values

coststr

Name of cost value column in cost_df (supply-side)

max_costfloat

Cutoff of cost values

weight_fnfunction

Weight to be applied to access values

normalizebool

If True, return normalized access values; otherwise, return raw access values

Returns:
accesspandas Series

Accessibility score for origin locations.

Examples

Import the base Access class and Datasets.

>>> from access import Access, Datasets

Load each of the example datasets:

>>> chi_docs_dents   = Datasets.load_data('chi_doc')
>>> chi_population   = Datasets.load_data('chi_pop')
>>> chi_travel_costs = Datasets.load_data('chi_times')
>>> chi_docs_dents.head()
         geoid  doc  dentist
0  17031010100    1        1
1  17031010201    0        1
2  17031010202    4        1
3  17031010300    4        1
4  17031010400    0        2
>>> chi_population.head()
         geoid   pop
0  17031010100  4854
1  17031010201  6450
2  17031010202  2818
3  17031010300  6236
4  17031010400  5042
>>> chi_travel_costs.head()
        origin         dest   cost
0  17093890101  17031010100  91.20
1  17093890101  17031010201  92.82
2  17093890101  17031010202  92.95
3  17093890101  17031010300  89.40
4  17093890101  17031010400  84.97

Using the example data, create an Access object.

>>> chicago_primary_care = Access(demand_df = chi_population, demand_index = "geoid",
                                  demand_value = "pop",
                                  supply_df = chi_docs_dents, supply_index = "geoid",
                                  supply_value = ["doc", "dentist"],
                                  cost_df = chi_travel_costs, cost_origin  = "origin",
                                  cost_dest = "destination", cost_name = "cost")
>>> chicago_primary_care.three_stage_fca(name='3sfca')
             3sfca_doc  3sfca_dentist
geoid
17031010100   0.001424       0.000690
17031010201   0.001462       0.000785
17031010202   0.001411       0.000767
...........   ........       ........
17197884101   0.000285       0.000380
17197884103   0.000404       0.000464
17197980100   0.000365       0.000407

The newly calculated 3sfca access measure is added to the access_df attribute of the Access object.

>>> chicago_primary_care.access_df.head()
                     3sfca_doc  3sfca_dentist
geoid
17031010100   0.001447       0.000698
17031010201   0.001487       0.000795
17031010202   0.001420       0.000777
17031010300   0.001479       0.000742
17031010400   0.001274       0.000726
two_stage_fca(name='2sfca', cost=None, max_cost=None, supply_values=None, weight_fn=None, normalize=False)[source]

Calculate the two-stage floating catchment area access score. Note that while the ‘traditional’ 2SFCA method does not weight inputs, most modern implementations do, and weight_fn is allowed as an argument.

Parameters:
namestr

Column name for access values

coststr

Name of cost value column in cost_df (supply-side)

supply_values{str, list}

supply type or types.

max_costfloat

Cutoff of cost values

weight_fnfunction

Weight to be applied to access values

normalizebool

If True, return normalized access values; otherwise, return raw access values

Returns:
accesspandas Series

Accessibility score for origin locations.

Examples

Import the base Access class and Datasets.

>>> from access import Access, Datasets

Load each of the example datasets:

>>> chi_docs_dents   = Datasets.load_data('chi_doc')
>>> chi_population   = Datasets.load_data('chi_pop')
>>> chi_travel_costs = Datasets.load_data('chi_times')
>>> chi_docs_dents.head()
         geoid  doc  dentist
0  17031010100    1        1
1  17031010201    0        1
2  17031010202    4        1
3  17031010300    4        1
4  17031010400    0        2
>>> chi_population.head()
         geoid   pop
0  17031010100  4854
1  17031010201  6450
2  17031010202  2818
3  17031010300  6236
4  17031010400  5042
>>> chi_travel_costs.head()
        origin         dest   cost
0  17093890101  17031010100  91.20
1  17093890101  17031010201  92.82
2  17093890101  17031010202  92.95
3  17093890101  17031010300  89.40
4  17093890101  17031010400  84.97

Using the example data, create an Access object.

>>> chicago_primary_care = Access(demand_df = chi_population, demand_index = "geoid",
                                  demand_value = "pop",
                                  supply_df = chi_docs_dents, supply_index = "geoid",
                                  supply_value = ["doc", "dentist"],
                                  cost_df = chi_travel_costs, cost_origin  = "origin",
                                  cost_dest = "destination", cost_name = "cost",
                                  neighbor_cost_df = chi_travel_costs, neighbor_cost_origin = "origin",
                                  neighbor_cost_dest = 'dest', neighbor_cost_name = 'cost')
>>> chicago_primary_care.two_stage_fca(name = '2sfca', max_cost = 60)
              pop  2sfca_doc  2sfca_dentist
geoid
17031010100  4854   0.000697       0.000402
17031010201  6450   0.000754       0.000455
17031010202  2818   0.000717       0.000424
...........  ....   ........       ........
17197884101  4166   0.000562       0.000370
17197884103  2776   0.000384       0.000291
17197980100  3264   0.000457       0.000325

To create new values for two-stage catchment areas using a different max_cost, you can use a new name and a different max_cost parameter.

>>> chicago_primary_care.two_stage_fca(name = '2sfca30', max_cost = 30)
             2sfca30_doc  2sfca30_dentist
geoid
17031010100     0.000966         0.000480
17031010201     0.000996         0.000552
17031010202     0.000973         0.000542
...........     ........         ........
17197884101     0.000225         0.000258
17197884103     0.000375         0.000382
17197980100     0.000352         0.000318

Both newly created two stage fca measures are stored in the access_df attribute of the Access object.

>>> chicago_primary_care.access_df.head()
              pop  2sfca_doc  2sfca_dentist  2sfca30_doc  2sfca30_dentist
geoid
17031010100  4854   0.000697       0.000402     0.000963         0.000479
17031010201  6450   0.000754       0.000455     0.000991         0.000551
17031010202  2818   0.000717       0.000424     0.000973         0.000541
17197884103  2776   0.000384       0.000291     0.000371         0.000377
17197980100  3264   0.000457       0.000325     0.000348         0.000314
weighted_catchment(name='catchment', supply_cost=None, supply_values=None, weight_fn=None, max_cost=None, normalize=False)[source]

Calculate the catchment area (buffer) aggregate access score.

Parameters:
namestr

Column name for access values

supply_coststr

Name of supply cost value column in supply_df

supply_values{str, list}

Name(s) of supply values in supply_df

weight_fnfunction

function to apply to the cost to reach the supply. In this way, you could run, e.g., a gravity function. (Be careful of course of values as distances go to 0!)

max_costfloat

Cutoff of cost values

normalizebool

If True, return normalized access values; otherwise, return raw access values

Returns:
accesspandas Series

Accessibility score for origin locations.

Examples

Create an Access object, as detailed in __init__.py

>>> illinois_primary_care = Access(<...>)

Call the floating catchment area with max_cost only

>>> gravity = weights.gravity(scale = 60, alpha = -1)
>>> illinois_primary_care.weighted_catchment(weight_fn = gravity)