At this point it is probably helpful to make concrete the topics discussed in
the introduction by giving code sample. There is also an IPython Notebook
in the Pandana repo which gives the entire workflow,
but the discussion here will take things line-by-line with a sufficient
summary of the functionality.

Note that these code samples assume you have imported pandas and pandana as follows:

First create the network. Although the API is incredibly simple,
this is likely to be the most difficult part of using Pandana. In the future
we will leverage the import functionality of tools like geopandas to
directly access networks via shapefiles,
but for now the initialization pandana.network.Network.__init__()
takes a small number of Pandas Series objects.

The network is comprised of a set of nodes and edges.
We store our nodes and edges as two Pandas DataFrames in an HDFStore object.
We can access them as follows (the demo data file can be
downloaded here):

The data structure is very simple indeed. Nodes have an index which is the
id of the node and an x-y position. Much like shapely, Pandana is
agnostic to the coordinate system. Use your local coordinate system or
longitude then latitude - either one will work. Edges are then ids (which
aren’t used) and
from node ids and to node_ids which should index directly to the node
DataFrame. A weight column (or multiple weight columns) is (are) required
as the impedance for the network. Here, distance is used from OpenStreetMap
edges.

It’s probably a good idea (though not strictly required) to precompute a
given horizon distance so that aggregations don’t perform the network queries
unnecessarily. This is done by calling the following code,
where 3000 meters is used as the horizon distance:

net.precompute(3000)

Note that a large amount of time is spent in the precomputations that take
place for these two lines of code. On a MacBook, these two lines of code
take 4 seconds and 8.5 seconds respectively.

This was done on a 4-core cpu, so if your precomputation is much slower,
check the IPython Notebook output (on the console) for a statement that saysGeneratingcontractionhierarchieswith4threads.If your output says
1 instead of 4 you are running single threaded. If you are running on
a multi-core cpu, there is probably a way to speed up the computation.

Now for the fun part. Nearest queries are slightly easier, so let’s cover that
first.

First initialize the POI (point-of-interest) category:

net.set_pois("restaurants",2000,10,x,y)

This code initializes the “restaurants” category with the positions specified
by the x and y columns (which are Pandas Series), at a max distance of 2000 meters
for up to the 10 nearest points-of-interest. Next perform the query:

This searches for the 10 nearest restaurants and is exactly the query that is
displayed in the introduction. This returns a DataFrame with the number of
columns equal to the number of POIs that are requested. For instance,
a describe of the output DataFrame look like this (note that the query
executed in half a second:

Performing a general network aggregation isn’t much harder. In this case,
it is assumed that DataFrames are much larger and that queries have
a lot more variety.

For this reason, the workflow is typically to map the variables x and y to
node_ids (which can then be cached or written to disk at a later date) and
to call set for each data column, potentially several times. For instance,
if you have a DataFrame of buildings with x and y coordinates,
you can use get_node_ids to set node_ids as an attribute on the
buildings table and then set can be called many times with all the
attributes of the buildings table and their associated column names.

An experimental feature for displaying the points of the node_ids and their
associated computed values using matplotlib (so that the entire workflow can
happen in the notebook) is also available.

Note that these have a bounding box for reducing the display window.
Although the underlying library is computing values for all nodes in the
region, it is difficult to visualize this much data using
matplotlib. For quick interactive checking of results,
the bounding box can be used to reduce the number of points that are shown,
and sample code and images are included below.