Skip to content

TrajDataFrame

TrajDataFrame is fastmob's general-purpose wrapper for timestamped latitude and longitude observations. It accepts eager Narwhals-compatible DataFrames, detects conventional column names, and records the resolved user, time, and coordinate metadata for later operations.

Required data

Provide latitude, longitude, and datetime columns; a user-ID column is optional. Pass explicit column names when automatic detection is not appropriate. The wrapper preserves the native backend and can sort observations by user and time.

import pandas as pd
from fastmob import TrajDataFrame

traj = TrajDataFrame(pd.DataFrame({
    "uid": [1, 1],
    "datetime": ["2024-01-01 08:00", "2024-01-01 08:10"],
    "lat": [47.37, 47.38],
    "lng": [8.54, 8.55],
}), sort=True)

jumps = traj.jump_lengths()

For typed hierarchy generation, use Positionfixes, which extends this class.

API

fastmob.core.trajectory_dataframe.TrajDataFrame

Bases: BaseDataFrame

Narwhals-backed wrapper for trajectory data.

Accepts any eager DataFrame backend (pandas, polars, …) and exposes a unified mobility-analysis API. Column names are auto-detected from a priority list; custom names can be supplied explicitly.

Parameters:

Name Type Description Default
df DataFrame - like

Source data. Accepted types: pandas.DataFrame, polars.DataFrame, any Narwhals-compatible eager frame, plain list, numpy.ndarray, or dict.

required
sort bool

If True, sort the underlying data by (uid, datetime) on construction. Default False.

False
timestamp bool

If True, parse the datetime column from Unix timestamps. Default False.

False
datetime_col str

Name of the datetime column in df (overrides auto-detection).

None
lat_col str

Name of the latitude column (overrides auto-detection).

None
lng_col str

Name of the longitude column (overrides auto-detection).

None
uid_col str

Name of the user-ID column (overrides auto-detection).

None
latitude str

Source column to rename to 'lat'.

None
longitude str

Source column to rename to 'lng'.

None
datetime str

Source column to rename to 'datetime'.

None
user_id str

Source column to rename to 'uid'.

None
trajectory_id str

Source column to rename to 'tid'.

None
crs dict

Coordinate reference system. Default {"init": "epsg:4326"}.

None
parameters dict

Arbitrary metadata dictionary. Default {}.

None

Examples:

>>> import pandas as pd
>>> import fastmob
>>> data = [
...     [1, 39.984094, 116.319236, "2008-10-23 13:53:05"],
...     [1, 39.984198, 116.319322, "2008-10-23 13:53:06"],
...     [1, 39.984224, 116.319402, "2008-10-23 13:53:11"],
... ]
>>> df = pd.DataFrame(data, columns=["uid", "lat", "lng", "datetime"])
>>> tdf = fastmob.TrajDataFrame(df)
>>> tdf.uid_col
'uid'

compress(spatial_radius_km=0.2, inplace=False)

Compress the trajectory by collapsing nearby consecutive points.

Parameters:

Name Type Description Default
spatial_radius_km float

Spatial radius (km) used to decide whether two consecutive points belong to the same stop. Default 0.2.

0.2
inplace bool

If True, modify this object and return self. If False (default), return a new TrajDataFrame.

False

Returns:

Type Description
TrajDataFrame

Examples:

>>> import pandas as pd
>>> import fastmob
>>> df = pd.DataFrame({
...     "uid": [1, 1, 1],
...     "lat": [0.0, 0.0001, 1.0],
...     "lng": [0.0, 0.0001, 0.0],
...     "datetime": pd.date_range("2020-01-01", periods=3, freq="h"),
... })
>>> tdf = fastmob.TrajDataFrame(df)
>>> tdf.compress()

interpolate(method='linear', sampling_rate_s=3600.0, **method_kwargs)

Fill gaps in the trajectory using a named interpolation algorithm.

Parameters:

Name Type Description Default
method str

One of "linear", "cubic_spline", "kinematic", or "random_walk". Default "linear".

'linear'
sampling_rate_s float

Maximum time gap, in seconds, allowed between consecutive points before an interpolated point is inserted. Default 3600.0.

3600.0
**method_kwargs

Method-specific parameters; see :func:fastmob.trajectory.interpolate.

{}

Returns:

Type Description
TrajDataFrame

Examples:

>>> import pandas as pd
>>> import fastmob
>>> df = pd.DataFrame({
...     "uid": [1, 1, 1],
...     "lat": [0.0, 1.0, 2.0],
...     "lng": [0.0, 0.0, 0.0],
...     "datetime": pd.to_datetime(
...         ["2020-01-01 00:00", "2020-01-01 02:00", "2020-01-01 03:00"]
...     ),
... })
>>> tdf = fastmob.TrajDataFrame(df)
>>> tdf.interpolate(sampling_rate_s=3600.0)

interpolate_at(at, method='linear')

Query the interpolated position of each user at one or more timestamps.

Parameters:

Name Type Description Default
at

A single timestamp-like, or a sequence of timestamp-likes.

required
method str

"linear" (default) or "nearest".

'linear'

Returns:

Type Description
DataFrame

One row per (uid, query_time) pair with lat, lng, and a valid column.

Examples:

>>> import pandas as pd
>>> import fastmob
>>> df = pd.DataFrame({
...     "uid": [1, 1, 1],
...     "lat": [0.0, 1.0, 2.0],
...     "lng": [0.0, 0.0, 0.0],
...     "datetime": pd.to_datetime(
...         ["2020-01-01 00:00", "2020-01-01 01:00", "2020-01-01 02:00"]
...     ),
... })
>>> tdf = fastmob.TrajDataFrame(df)
>>> tdf.interpolate_at("2020-01-01 00:30")

jump_lengths(merge=False)

Compute the jump lengths (km) between consecutive GPS points.

Parameters:

Name Type Description Default
merge bool

If True, merge the result back onto the original DataFrame. Default False.

False

Returns:

Type Description
DataFrame

A DataFrame with columns uid (when a user column is present) and jump_lengths containing a list of distances per user.

Examples:

>>> import pandas as pd
>>> import fastmob
>>> df = pd.DataFrame({
...     "uid": [1, 1, 1],
...     "lat": [0.0, 1.0, 2.0],
...     "lng": [0.0, 0.0, 0.0],
...     "datetime": pd.date_range("2020-01-01", periods=3, freq="h"),
... })
>>> tdf = fastmob.TrajDataFrame(df)
>>> tdf.jump_lengths()

mapping(tessellation, remove_na=False)

Assign each trajectory point to a tile in a spatial tessellation.

Adds a tile_id column to the result.

Parameters:

Name Type Description Default
tessellation GeoDataFrame

Spatial tessellation with Polygon or Point geometries and a tile_id column.

required
remove_na bool

If True, remove points that fall outside the tessellation. Default False (keep them with NaN tile_id).

False

Returns:

Type Description
TrajDataFrame

Original trajectory with an extra tile_id column.

Notes

Requires fastmob[geo]::

pip install "fastmob[geo]"

Examples:

>>> import fastmob
>>> tdf = fastmob.data.load_dataset("foursquare_nyc")
>>> from fastmob.tessellation.tilers import tiler
>>> tess = tiler.get("squared", base_shape="New York City", meters=2000)
>>> mapped = tdf.mapping(tess)

radius_of_gyration()

Compute the radius of gyration (km) for each user.

Returns:

Type Description
DataFrame

A DataFrame with columns uid (when present) and radius_of_gyration.

Examples:

>>> import pandas as pd
>>> import fastmob
>>> df = pd.DataFrame({
...     "uid": [1, 1, 1],
...     "lat": [0.0, 1.0, 2.0],
...     "lng": [0.0, 0.0, 0.0],
...     "datetime": pd.date_range("2020-01-01", periods=3, freq="h"),
... })
>>> tdf = fastmob.TrajDataFrame(df)
>>> tdf.radius_of_gyration()

settings_from(other)

Copy metadata attributes from another TrajDataFrame.

Parameters:

Name Type Description Default
other TrajDataFrame

Source TrajDataFrame to copy attributes from.

required

Examples:

>>> import pandas as pd
>>> import fastmob
>>> df = pd.DataFrame({
...     "uid": [1], "lat": [0.0], "lng": [0.0],
...     "datetime": pd.date_range("2020-01-01", periods=1),
... })
>>> tdf1 = fastmob.TrajDataFrame(df.copy())
>>> tdf2 = fastmob.TrajDataFrame(df.copy(), parameters={"source": "gps"})
>>> tdf1.settings_from(tdf2)
>>> tdf1.parameters
{'source': 'gps'}

smooth(method='kalman_cv', **method_kwargs)

Smooth the trajectory's positions using a named algorithm.

Unlike :meth:interpolate, row count and row order are unchanged -- every point's (lat, lng) is replaced with a denoised estimate at its original timestamp.

Parameters:

Name Type Description Default
method str

Only "kalman_cv" is shipped currently. Default "kalman_cv".

'kalman_cv'
**method_kwargs

Method-specific parameters; see :func:fastmob.trajectory.smooth.

{}

Returns:

Type Description
TrajDataFrame

Examples:

>>> import pandas as pd
>>> import fastmob
>>> df = pd.DataFrame({
...     "uid": [1, 1, 1],
...     "lat": [0.0, 1.0, 2.0],
...     "lng": [0.0, 0.0, 0.0],
...     "datetime": pd.date_range("2020-01-01", periods=3, freq="h"),
... })
>>> tdf = fastmob.TrajDataFrame(df)
>>> tdf.smooth()

sort_by_uid_and_datetime()

Return a copy sorted by user ID then datetime.

Returns:

Type Description
TrajDataFrame

New TrajDataFrame with rows sorted ascending by (uid, datetime).

Examples:

>>> import pandas as pd
>>> import fastmob
>>> df = pd.DataFrame({
...     "uid": [2, 1, 1],
...     "lat": [0.0, 1.0, 2.0],
...     "lng": [0.0, 0.0, 0.0],
...     "datetime": pd.date_range("2020-01-01", periods=3, freq="h"),
... })
>>> tdf = fastmob.TrajDataFrame(df)
>>> sorted_tdf = tdf.sort_by_uid_and_datetime()

stay_locations(inplace=False, **kwargs)

Detect stay locations (stops) in the trajectory.

Parameters:

Name Type Description Default
inplace bool

If True, modify this object and return self. If False (default), return a new TrajDataFrame.

False
**kwargs

Extra keyword arguments forwarded to fastmob.preprocessing.stay_locations.

{}

Returns:

Type Description
TrajDataFrame

A DataFrame whose rows are detected stops, with an extra leaving_datetime column.

Examples:

>>> import pandas as pd
>>> import fastmob
>>> df = pd.DataFrame({
...     "uid": [1, 1, 1, 1],
...     "lat": [0.0, 0.0001, 0.0, 1.0],
...     "lng": [0.0, 0.0, 0.0001, 0.0],
...     "datetime": pd.date_range("2020-01-01", periods=4, freq="30min"),
... })
>>> tdf = fastmob.TrajDataFrame(df)
>>> tdf.stay_locations(minutes_for_a_stop=20)

timezone_conversion(from_timezone, to_timezone)

Convert the datetime column from one timezone to another, in place.

The result has timezone information stripped (tz-naive), matching the behaviour of the original scikit-mobility implementation.

Parameters:

Name Type Description Default
from_timezone str

Current timezone of the datetime column, e.g. 'GMT'.

required
to_timezone str

Target timezone, e.g. 'Asia/Shanghai'.

required

Examples:

>>> import pandas as pd
>>> import fastmob
>>> df = pd.DataFrame({
...     "uid": [1, 1],
...     "lat": [39.984, 39.985],
...     "lng": [116.319, 116.320],
...     "datetime": pd.to_datetime(["2008-10-23 05:53:05", "2008-10-23 05:53:06"]),
... })
>>> tdf = fastmob.TrajDataFrame(df)
>>> tdf.timezone_conversion("GMT", "Asia/Shanghai")
>>> tdf[tdf.datetime_col].iloc[0]
Timestamp('2008-10-23 13:53:05')

to_flowdataframe(tessellation, self_loops=True)

Aggregate the trajectory into a FlowDataFrame using a tessellation.

Points outside the tessellation are silently dropped.

Parameters:

Name Type Description Default
tessellation GeoDataFrame

Spatial tessellation with a tile_id column and polygon geometries.

required
self_loops bool

If True (default), include movements that start and end in the same tile.

True

Returns:

Type Description
FlowDataFrame
Notes

Requires fastmob[geo]::

pip install "fastmob[geo]"

Examples:

>>> import fastmob
>>> tdf = fastmob.data.load_dataset("foursquare_nyc")
>>> from fastmob.tessellation.tilers import tiler
>>> tess = tiler.get("squared", base_shape="New York City", meters=2000)
>>> fdf = tdf.to_flowdataframe(tess)

to_geodataframe()

Convert to a geopandas.GeoDataFrame with Point geometry.

Returns:

Type Description
GeoDataFrame

Same rows as the trajectory, with an additional geometry column containing shapely.geometry.Point objects built from the latitude and longitude columns.

Notes

Requires fastmob[geo]::

pip install "fastmob[geo]"

Examples:

>>> import pandas as pd
>>> import fastmob
>>> df = pd.DataFrame({
...     "uid": [1, 1],
...     "lat": [48.8566, 48.8578],
...     "lng": [2.3522, 2.3530],
...     "datetime": pd.date_range("2020-01-01", periods=2, freq="h"),
... })
>>> tdf = fastmob.TrajDataFrame(df)
>>> gdf = tdf.to_geodataframe()

trajectory_distance(other, method='dtw', **method_kwargs)

Compute a similarity/distance metric against another trajectory's point-sequence.

Parameters:

Name Type Description Default
other

Another trajectory (any Narwhals-compatible eager backend, or a TrajDataFrame). Must represent a single user's point-sequence.

required
method str

One of "dtw", "frechet", "hausdorff", or "lcss". Default "dtw".

'dtw'
**method_kwargs

Method-specific parameters; see :func:fastmob.trajectory.trajectory_distance.

{}

Returns:

Type Description
float

Examples:

>>> import pandas as pd
>>> import fastmob
>>> df = pd.DataFrame({
...     "lat": [0.0, 1.0, 2.0], "lng": [0.0, 0.0, 0.0],
...     "datetime": pd.date_range("2020-01-01", periods=3, freq="h"),
... })
>>> tdf = fastmob.TrajDataFrame(df)
>>> tdf.trajectory_distance(df, method="dtw")
0.0

work_location(**kwargs)

Infer the most-visited weekday daytime location for each user.

Delegates to :func:fastmob.measures.individual.work_location using this dataframe's resolved column metadata and sorted fast path.

Parameters:

Name Type Description Default
**kwargs

Forwarded to :func:fastmob.measures.individual.work_location.

{}

Returns:

Type Description
DataFrame

Inferred weekday daytime location for each user.

Examples:

>>> workplaces = tdf.work_location()