Skip to content

Trajectory

API Description
interpolate Fill gaps in a trajectory by inserting interpolated points.
interpolate_at Query each user's interpolated position at one or more timestamps.
trajectory_distance Compute a similarity/distance metric between two trajectories.

fastmob.trajectory.interpolate(traj, method='linear', sampling_rate_s=3600.0, *, datetime_col=None, lat_col=None, lng_col=None, uid_col=None, **method_kwargs)

Fill gaps in a trajectory by inserting interpolated points.

For every gap between two chronologically consecutive points of the same user whose time delta exceeds sampling_rate_s, exactly one new point is inserted at t[i-1] + sampling_rate_s (matching PTRAIL's Interpolation.interpolate_position insertion policy: a large gap is not filled iteratively down to sampling_rate_s-sized steps -- only one point is added per gap, regardless of how large it is).

Parameters:

Name Type Description Default
traj Any

Trajectory dataframe; any Narwhals-compatible eager backend.

required
method str

Name of the interpolation algorithm to run. One of "linear", "cubic_spline", "kinematic", or "random_walk".

'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
datetime_col str | None

Explicit column name overrides; auto-detected when None.

None
lat_col str | None

Explicit column name overrides; auto-detected when None.

None
lng_col str | None

Explicit column name overrides; auto-detected when None.

None
uid_col str | None

Explicit column name overrides; auto-detected when None.

None
**method_kwargs Any

Method-specific parameters, forwarded to the matching INTERPOLATE_METHODS[method] preparer.

  • linear, cubic_spline: no extra parameters.
  • kinematic: max_speed_kmh (default 300.0) -- safety clamp; a gap falls back to linear interpolation if the fitted kinematic position implies a speed above this bound from the preceding point.
  • random_walk: step_std_km (default 0.01) -- half-normal standard deviation, in km, of the random perturbation applied on top of the linear-interpolated base position; seed (default 0) -- RNG seed; each user draws an independent, seed-derived sequence, so results are reproducible but do not attempt to reproduce any other library's own random draws.
{}

Returns:

Type Description
DataFrame

The expanded trajectory (original points, plus any inserted points) in the same backend as input, sorted chronologically 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.to_datetime(
...         ["2020-01-01 00:00", "2020-01-01 02:00", "2020-01-01 03:00"]
...     ),
... })
>>> from fastmob.trajectory import interpolate
>>> out = interpolate(df, method="linear", sampling_rate_s=3600.0)
>>> len(out) >= len(df)
True
References
  • [PTRAIL] Haranwala, Y.J., & Haidri, S. PTRAIL: A Python package for parallel trajectory data preprocessing.
  • [Nogueira2016] Nogueira, T.O. "kinematic_interpolation.py" (2016).

fastmob.trajectory.interpolate_at(traj, at, method='linear', *, datetime_col=None, lat_col=None, lng_col=None, uid_col=None)

Query each user's interpolated position at one or more timestamps.

Unlike :func:fastmob.trajectory.interpolate, this never changes a user's own point count -- it answers "where was this user at time t?" independently per user and per query timestamp. A query time outside a user's own [min(datetime), max(datetime)] range is marked invalid (valid=False, NaN position) rather than raising, matching this codebase's validity-mask convention over exceptions.

Parameters:

Name Type Description Default
traj Any

Trajectory dataframe; any Narwhals-compatible eager backend.

required
at Any

A single timestamp-like, or a sequence of timestamp-likes. Every user is queried at every timestamp in at.

required
method str

"linear" (default) interpolates position between the two surrounding points; "nearest" returns the closer of the two.

'linear'
datetime_col str | None

Explicit column name overrides; auto-detected when None.

None
lat_col str | None

Explicit column name overrides; auto-detected when None.

None
lng_col str | None

Explicit column name overrides; auto-detected when None.

None
uid_col str | None

Explicit column name overrides; auto-detected when None.

None

Returns:

Type Description
DataFrame

One row per (uid, query_time) pair (or one row per query timestamp when no user column is present), with columns uid (when present), query_time, lat_col, lng_col, and valid.

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"]
...     ),
... })
>>> from fastmob.trajectory import interpolate_at
>>> out = interpolate_at(df, at="2020-01-01 00:30", method="linear")
>>> bool(out["valid"].iloc[0])
True

fastmob.trajectory.trajectory_distance(traj_a, traj_b, method='dtw', *, datetime_col_a=None, lat_col_a=None, lng_col_a=None, uid_col_a=None, datetime_col_b=None, lat_col_b=None, lng_col_b=None, uid_col_b=None, **method_kwargs)

Compute a similarity/distance metric between two trajectories.

Compares exactly two whole point-sequences -- each side must be a single user's trajectory (or have no user column at all), not a multi-user dataframe. Point-to-point distances are computed via haversine, matching every other fastmob measure's geographic-distance convention.

Parameters:

Name Type Description Default
traj_a Any

Trajectory dataframes; any Narwhals-compatible eager backend, or a TrajDataFrame.

required
traj_b Any

Trajectory dataframes; any Narwhals-compatible eager backend, or a TrajDataFrame.

required
method str

"dtw", "frechet", or "hausdorff" return a distance in km (0 = identical shape); "lcss" returns a similarity in [0, 1] (1 = identical shape).

'dtw'
datetime_col_a str | None

Explicit column overrides for traj_a; auto-detected when None.

None
lat_col_a str | None

Explicit column overrides for traj_a; auto-detected when None.

None
lng_col_a str | None

Explicit column overrides for traj_a; auto-detected when None.

None
uid_col_a str | None

Explicit column overrides for traj_a; auto-detected when None.

None
datetime_col_b str | None

Explicit column overrides for traj_b; auto-detected when None.

None
lat_col_b str | None

Explicit column overrides for traj_b; auto-detected when None.

None
lng_col_b str | None

Explicit column overrides for traj_b; auto-detected when None.

None
uid_col_b str | None

Explicit column overrides for traj_b; auto-detected when None.

None
**method_kwargs Any

Method-specific parameters, forwarded to the matching DISTANCE_METHODS[method] preparer.

  • lcss: epsilon_km (default 0.1) -- two points are considered a match when their haversine distance is within this threshold.
{}

Returns:

Type Description
float

Raises:

Type Description
ValueError

If either side's user-ID column contains more than one distinct user.

Examples:

>>> import pandas as pd
>>> import fastmob
>>> traj_a = 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"),
... })
>>> traj_b = pd.DataFrame({
...     "lat": [0.0, 1.0, 2.0], "lng": [0.1, 0.1, 0.1],
...     "datetime": pd.date_range("2020-01-01", periods=3, freq="h"),
... })
>>> from fastmob.trajectory import trajectory_distance
>>> trajectory_distance(traj_a, traj_b, method="dtw") > 0
True
References
  • [Vlachos2002] Vlachos, M., Kollios, G., & Gunopulos, D. (2002). Discovering similar multidimensional trajectories. ICDE 2002.