Skip to content

Mobility analysis, hundreds of times faster

Fastkit-Mobility cleans GPS traces, finds stops and trips, and measures how people move. Rust does the heavy lifting; you keep your pandas or Polars dataframes.

Average time on 4 million Brightkite check-ins, Fastkit-Mobility (pandas) versus scikit-mobility. All measures and methodology.

Bar chart comparing scikit-mobility and Fastkit-Mobility execution time on 4M check-ins for five measures; Fastkit-Mobility is 423x to 2658x faster.

Try it

pip install fastmob
import pandas as pd
from fastmob import radius_of_gyration

df = pd.DataFrame({
    "uid": ["alice"] * 3 + ["bob"] * 3,
    "datetime": pd.to_datetime(["2020-01-01 08:00", "2020-01-01 09:00", "2020-01-01 10:00"] * 2),
    "lat": [41.9, 42.0, 42.1, 40.7, 40.8, 41.0],
    "lng": [12.5, 12.5, 12.6, -74.0, -74.0, -73.9],
})

radius_of_gyration(df)  # km each user ranges around their center
     uid  radius_of_gyration
0  alice            9.878827
1    bob           14.423721
import polars as pl
from fastmob import radius_of_gyration

df = pl.DataFrame({
    "uid": ["alice"] * 3 + ["bob"] * 3,
    "datetime": ["2020-01-01 08:00", "2020-01-01 09:00", "2020-01-01 10:00"] * 2,
    "lat": [41.9, 42.0, 42.1, 40.7, 40.8, 41.0],
    "lng": [12.5, 12.5, 12.6, -74.0, -74.0, -73.9],
}).with_columns(pl.col("datetime").str.to_datetime())

radius_of_gyration(df)  # returns a Polars DataFrame
uid      radius_of_gyration
"alice"  9.878827
"bob"    14.423721

From raw GPS fixes to tours

Each level of the hierarchy is derived from the one below it with a single method call.

Diagram: Positionfixes produce Staypoints and Triplegs; these combine into Trips, then Tours. Staypoints also cluster into Locations, which tours return to.

What you can do

One GeoLife user-day: grey position fixes, coloured triplegs between stops, and gold circles at detected staypoints.

One day of a GeoLife user in Beijing: Fastkit-Mobility turns raw fixes into staypoints and triplegs.

Why Fastkit-Mobility

  • Familiar API. Measure names and signatures follow scikit-mobility, so existing code ports easily, and comparison tests check the results.
  • Any dataframe, no copies. Narwhals accepts pandas, Polars and other eager backends and returns the same type; Rust kernels read your columns in place.

Requires Python 3.9 or later. Prebuilt wheels are available, so no Rust toolchain is needed to install; building from source is covered in development setup.

Next steps