Collective Measures
| API | Description |
|---|---|
homes_per_location |
Return the number of users whose home is at each distinct location. |
mean_square_displacement |
Return the mean square displacement (km^2) across all users. |
random_location_entropy |
Return the random entropy for each distinct location across all users. |
uncorrelated_location_entropy |
Return the uncorrelated entropy for each distinct location across all users. |
visits_per_location |
Return the total number of visits for each distinct global location ID. |
visits_per_time_unit |
Return the number of trajectory points per time unit across all users. |
od_matrix |
Compute an Origin-Destination matrix from a trips DataFrame. |
od_metrics_per_area |
Compute per-area mobility metrics from a long-format OD DataFrame. |
mean_area_volume |
Mean user volume per area and 10-minute time bin, averaged across days of the week. |
build_stvd |
Aggregate staypoints against a global Locations catalogue into an STVD frame. |
fastmob.measures.collective.homes_per_location
homes_per_location(traj, *, start_night=22, end_night=7, datetime_col=None, lat_col=None, lng_col=None, uid_col=None)
Return the number of users whose home is at each distinct location.
The number of home locations at location \(j\) is computed as [PRS2016]_:
where \(h_u\) indicates the home location of individual \(u\)
(see :func:~fastmob.measures.individual.home_location) and \(U\)
is the set of all individuals.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
traj
|
DataFrame - like
|
Trajectory dataframe; any Narwhals-compatible eager backend (pandas, polars, …). Must have datetime, latitude, and longitude columns. |
required |
start_night
|
int
|
Hour (0–23) at which the nighttime window begins. Default: 22. |
22
|
end_night
|
int
|
Hour (0–23) at which the nighttime window ends (exclusive). Default: 7. |
7
|
datetime_col
|
str or None
|
Explicit datetime column name. Auto-detected when None. |
None
|
lat_col
|
str or None
|
Explicit latitude column name. Auto-detected when None. |
None
|
lng_col
|
str or None
|
Explicit longitude column name. Auto-detected when None. |
None
|
uid_col
|
str or None
|
Explicit user-ID column name. Auto-detected when None. |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame or DataFrame
|
One row per distinct home location with columns
|
Examples:
>>> import pandas as pd
>>> import fastmob
>>> url = fastmob.data.BRIGHTKITE_SAMPLE
>>> df = pd.read_csv(
... url,
... sep="\t",
... header=0,
... nrows=5000,
... names=["uid", "datetime", "lat", "lng", "location id"],
... )
>>> df["datetime"] = pd.to_datetime(df["datetime"], errors="coerce")
>>> df["location_id"] = df["location id"].astype("string")
>>> df = df.dropna(subset=["uid", "datetime", "lat", "lng"])[
... ["uid", "datetime", "lat", "lng", "location_id"]
... ]
>>> print(df.head().to_string(index=False))
uid datetime lat lng location_id
0 2010-10-16 06:02:04+00:00 39.891383 -105.070814 7a0f88982aa015062b95e3b4843f9ca2
0 2010-10-16 03:48:54+00:00 39.891077 -105.068532 dd7cd3d264c2d063832db506fba8bf79
0 2010-10-14 18:25:51+00:00 39.750469 -104.999073 9848afcc62e500a01cf6fbf24b797732f8963683
0 2010-10-14 00:21:47+00:00 39.752713 -104.996337 2ef143e12038c870038df53e0478cefc
0 2010-10-13 23:31:51+00:00 39.752508 -104.996637 424eb3dd143292f9e013efa00486c907
>>> from fastmob import homes_per_location
>>> result = homes_per_location(df)
>>> print(result.round({"lat": 3, "lng": 3}).head().to_string(index=False))
lat lng n_homes
39.891 -105.069 1
37.630 -122.411 1
39.739 -104.985 1
References
- [PRS2016] Pappalardo, L., Rinzivillo, S. & Simini, F. (2016) Human Mobility Modelling: exploration and preferential return meet the gravity model. Procedia Computer Science 83, 934-939, http://dx.doi.org/10.1016/j.procs.2016.04.188
See Also
visits_per_location : Total visit count per location across all users. home_location : Inferred home location from nighttime visits (individual measure).
fastmob.measures.collective.mean_square_displacement
mean_square_displacement(traj, *, days=0, hours=1, minutes=0, datetime_col=None, lat_col=None, lng_col=None, uid_col=None)
Return the mean square displacement (km²) across all users.
The mean squared displacement (MSD) measures the average deviation of position from a reference point over time [FS2002] [BHG2006] [SKWB2010]_:
where \(N\) is the number of individuals, \(r^{(i)}(0)\) is the reference position (first recorded point) of individual \(i\), and \(r^{(i)}(t)\) is their position at time offset \(t\).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
traj
|
DataFrame - like
|
Trajectory dataframe; any Narwhals-compatible eager backend (pandas, polars, …). Must have datetime, latitude, and longitude columns. |
required |
days
|
int
|
Days component of the time offset from each user's start time. Defaults to 0. |
0
|
hours
|
int
|
Hours component of the time offset. Defaults to 1. |
1
|
minutes
|
int
|
Minutes component of the time offset. Defaults to 0. |
0
|
datetime_col
|
str or None
|
Explicit datetime column name. Auto-detected when None. |
None
|
lat_col
|
str or None
|
Explicit latitude column name. Auto-detected when None. |
None
|
lng_col
|
str or None
|
Explicit longitude column name. Auto-detected when None. |
None
|
uid_col
|
str or None
|
Explicit user-ID column name. Auto-detected when None. |
None
|
Returns:
| Type | Description |
|---|---|
float
|
Mean square displacement in km². Returns 0.0 when the trajectory is empty or every user's displacement window is trivially at the start. |
Examples:
>>> import pandas as pd
>>> import fastmob
>>> url = fastmob.data.BRIGHTKITE_SAMPLE
>>> df = pd.read_csv(
... url,
... sep="\t",
... header=0,
... nrows=5000,
... names=["uid", "datetime", "lat", "lng", "location id"],
... )
>>> df["datetime"] = pd.to_datetime(df["datetime"], errors="coerce")
>>> df["location_id"] = df["location id"].astype("string")
>>> df = df.dropna(subset=["uid", "datetime", "lat", "lng"])[
... ["uid", "datetime", "lat", "lng", "location_id"]
... ]
>>> print(df.head().to_string(index=False))
uid datetime lat lng location_id
0 2010-10-16 06:02:04+00:00 39.891383 -105.070814 7a0f88982aa015062b95e3b4843f9ca2
0 2010-10-16 03:48:54+00:00 39.891077 -105.068532 dd7cd3d264c2d063832db506fba8bf79
0 2010-10-14 18:25:51+00:00 39.750469 -104.999073 9848afcc62e500a01cf6fbf24b797732f8963683
0 2010-10-14 00:21:47+00:00 39.752713 -104.996337 2ef143e12038c870038df53e0478cefc
0 2010-10-13 23:31:51+00:00 39.752508 -104.996637 424eb3dd143292f9e013efa00486c907
>>> from fastmob import mean_square_displacement
>>> result = mean_square_displacement(df)
>>> print(round(result, 3))
128.583
References
- [FS2002] Frenkel, D. & Smit, B. (2002) Understanding molecular simulation: From algorithms to applications. Academic Press, 196 (2nd Ed.), https://www.sciencedirect.com/book/9780122673511/understanding-molecular-simulation.
- [BHG2006] Brockmann, D., Hufnagel, L. & Geisel, T. (2006) The scaling laws of human travel. Nature 439, 462-465, https://www.nature.com/articles/nature04292
- [SKWB2010] Song, C., Koren, T., Wang, P. & Barabasi, A.L. (2010) Modelling the scaling properties of human mobility. Nature Physics 6, 818-823, https://www.nature.com/articles/nphys1760
fastmob.measures.collective.random_location_entropy
random_location_entropy(traj, *, datetime_col=None, lat_col=None, lng_col=None, uid_col=None)
Return the random entropy for each distinct location across all users.
Random location entropy is \(\log_2(n)\), where \(n\) is the number of
distinct users who visited the location. A location is a unique exact
(lat, lng) pair — matching the skmob convention.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
traj
|
DataFrame - like
|
Trajectory dataframe; any Narwhals-compatible eager backend (pandas, polars, …). Must have datetime, latitude, and longitude columns. A user-ID column is optional; when absent all rows are treated as coming from a single individual (entropy will be 0 everywhere). |
required |
datetime_col
|
str or None
|
Explicit datetime column name. Auto-detected when None. |
None
|
lat_col
|
str or None
|
Explicit latitude column name. Auto-detected when None. |
None
|
lng_col
|
str or None
|
Explicit longitude column name. Auto-detected when None. |
None
|
uid_col
|
str or None
|
Explicit user-ID column name. Auto-detected when None. |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame or DataFrame
|
One row per distinct |
Examples:
>>> import pandas as pd
>>> import fastmob
>>> url = fastmob.data.BRIGHTKITE_SAMPLE
>>> df = pd.read_csv(
... url,
... sep="\t",
... header=0,
... nrows=5000,
... names=["uid", "datetime", "lat", "lng", "location id"],
... )
>>> df["datetime"] = pd.to_datetime(df["datetime"], errors="coerce")
>>> df["location_id"] = df["location id"].astype("string")
>>> df = df.dropna(subset=["uid", "datetime", "lat", "lng"])[
... ["uid", "datetime", "lat", "lng", "location_id"]
... ]
>>> print(df.head().to_string(index=False))
uid datetime lat lng location_id
0 2010-10-16 06:02:04+00:00 39.891383 -105.070814 7a0f88982aa015062b95e3b4843f9ca2
0 2010-10-16 03:48:54+00:00 39.891077 -105.068532 dd7cd3d264c2d063832db506fba8bf79
0 2010-10-14 18:25:51+00:00 39.750469 -104.999073 9848afcc62e500a01cf6fbf24b797732f8963683
0 2010-10-14 00:21:47+00:00 39.752713 -104.996337 2ef143e12038c870038df53e0478cefc
0 2010-10-13 23:31:51+00:00 39.752508 -104.996637 424eb3dd143292f9e013efa00486c907
>>> from fastmob import random_location_entropy
>>> result = random_location_entropy(df)
>>> print(result.round({"random_entropy": 3}).head().to_string(index=False))
lat lng random_entropy
0.000000 0.000000 1.585
29.532220 -98.300914 0.000
29.942673 -90.064455 0.000
29.948116 -90.063436 0.000
29.948125 -90.063510 0.000
See Also
uncorrelated_location_entropy : Location entropy weighted by visitor frequency.
fastmob.measures.collective.uncorrelated_location_entropy
uncorrelated_location_entropy(traj, *, datetime_col=None, lat_col=None, lng_col=None, uid_col=None)
Return the uncorrelated entropy for each distinct location across all users.
For each location l, computes the Shannon entropy over the distribution
of visit probabilities:
where \(p(u, l)\) is the fraction of all visits to \(l\) that belong to
user \(u\). A location is a unique exact (lat, lng) pair.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
traj
|
DataFrame - like
|
Trajectory dataframe; any Narwhals-compatible eager backend (pandas, polars, …). Must have datetime, latitude, and longitude columns. A user-ID column is optional; when absent all rows are treated as coming from a single individual (entropy will be 0 everywhere). |
required |
datetime_col
|
str or None
|
Explicit datetime column name. Auto-detected when None. |
None
|
lat_col
|
str or None
|
Explicit latitude column name. Auto-detected when None. |
None
|
lng_col
|
str or None
|
Explicit longitude column name. Auto-detected when None. |
None
|
uid_col
|
str or None
|
Explicit user-ID column name. Auto-detected when None. |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame or DataFrame
|
One row per distinct |
Examples:
>>> import pandas as pd
>>> import fastmob
>>> url = fastmob.data.BRIGHTKITE_SAMPLE
>>> df = pd.read_csv(
... url,
... sep="\t",
... header=0,
... nrows=5000,
... names=["uid", "datetime", "lat", "lng", "location id"],
... )
>>> df["datetime"] = pd.to_datetime(df["datetime"], errors="coerce")
>>> df["location_id"] = df["location id"].astype("string")
>>> df = df.dropna(subset=["uid", "datetime", "lat", "lng"])[
... ["uid", "datetime", "lat", "lng", "location_id"]
... ]
>>> print(df.head().to_string(index=False))
uid datetime lat lng location_id
0 2010-10-16 06:02:04+00:00 39.891383 -105.070814 7a0f88982aa015062b95e3b4843f9ca2
0 2010-10-16 03:48:54+00:00 39.891077 -105.068532 dd7cd3d264c2d063832db506fba8bf79
0 2010-10-14 18:25:51+00:00 39.750469 -104.999073 9848afcc62e500a01cf6fbf24b797732f8963683
0 2010-10-14 00:21:47+00:00 39.752713 -104.996337 2ef143e12038c870038df53e0478cefc
0 2010-10-13 23:31:51+00:00 39.752508 -104.996637 424eb3dd143292f9e013efa00486c907
>>> from fastmob import uncorrelated_location_entropy
>>> result = uncorrelated_location_entropy(df)
>>> print(result.round({"uncorrelated_entropy": 3}).head().to_string(index=False))
lat lng uncorrelated_entropy
0.000000 0.000000 0.911
29.532220 -98.300914 0.000
29.942673 -90.064455 0.000
29.948116 -90.063436 0.000
29.948125 -90.063510 0.000
References
- [CML2011] Cho, E., Myers, S. A. & Leskovec, J. (2011) Friendship and mobility: user movement in location-based social networks. In Proceedings of the 17th ACM SIGKDD international conference on Knowledge discovery and data mining, 1082-1090, https://dl.acm.org/citation.cfm?id=2020579
See Also
random_location_entropy : Baseline entropy assuming uniform visitation across users.
fastmob.measures.collective.visits_per_location
visits_per_location(traj, *, datetime_col=None, location_id_col=None, uid_col=None)
Return the total number of visits for each distinct location.
Counts all trajectory rows (visits) per unique location ID across all
users. Location IDs must be global-scoped, so the same ID represents the
same location for every user. This is the population-level analogue of
per-user location_frequency.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
traj
|
DataFrame - like
|
Trajectory dataframe; any Narwhals-compatible eager backend (pandas, polars, …). Must have datetime and a globally scoped location-ID column. |
required |
datetime_col
|
str or None
|
Explicit datetime column name. Auto-detected when None. |
None
|
location_id_col
|
str or None
|
Explicit location-ID column name. Auto-detected when None. IDs must be global-scoped rather than user-scoped. |
None
|
uid_col
|
str or None
|
Explicit user-ID column name. Auto-detected when None (not used for aggregation, but retained for API consistency). |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame or DataFrame
|
One row per distinct location ID with columns
|
Examples:
>>> import pandas as pd
>>> import fastmob
>>> url = fastmob.data.BRIGHTKITE_SAMPLE
>>> df = pd.read_csv(
... url,
... sep="\t",
... header=0,
... nrows=5000,
... names=["uid", "datetime", "lat", "lng", "location id"],
... )
>>> df["datetime"] = pd.to_datetime(df["datetime"], errors="coerce")
>>> df["location_id"] = df["location id"].astype("string")
>>> df = df.dropna(subset=["uid", "datetime", "location_id"])[
... ["uid", "datetime", "location_id"]
... ]
>>> print(df.head().to_string(index=False))
uid datetime location_id
0 2010-10-16 06:02:04+00:00 7a0f88982aa015062b95e3b4843f9ca2
0 2010-10-16 03:48:54+00:00 dd7cd3d264c2d063832db506fba8bf79
0 2010-10-14 18:25:51+00:00 9848afcc62e500a01cf6fbf24b797732f8963683
0 2010-10-14 00:21:47+00:00 2ef143e12038c870038df53e0478cefc
0 2010-10-13 23:31:51+00:00 424eb3dd143292f9e013efa00486c907
>>> from fastmob import visits_per_location
>>> result = visits_per_location(df)
>>> print(result.head().to_string(index=False))
location_id n_visits
7a0f88982aa015062b95e3b4843f9ca2 340
dd7cd3d264c2d063832db506fba8bf79 297
9848afcc62e500a01cf6fbf24b797732f8963683 297
2ef143e12038c870038df53e0478cefc 249
424eb3dd143292f9e013efa00486c907 232
References
- [PF2018] Pappalardo, L. & Simini, F. (2018) Data-driven generation of spatio-temporal routines in human mobility. Data Mining and Knowledge Discovery 32, 787-829, https://link.springer.com/article/10.1007/s10618-017-0548-4
See Also
homes_per_location : Number of users whose home is at each location. location_frequency : Per-user visit frequency (individual measure).
fastmob.measures.collective.visits_per_time_unit
visits_per_time_unit(traj, time_unit=None, *, freq='1h', datetime_col=None, lat_col=None, lng_col=None, uid_col=None)
Return the number of trajectory points per time unit across all users.
Groups all trajectory records by time bins of width freq and counts
the number of records (visits) in each bin. The result covers only bins
that contain at least one record.
The freq parameter follows pandas offset alias syntax (e.g. "1h",
"1D", "15min"). Results are returned using the same dataframe
backend as the input.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
traj
|
DataFrame - like
|
Trajectory dataframe; any Narwhals-compatible eager backend (pandas, polars, …). Must have datetime, latitude, and longitude columns. |
required |
time_unit
|
str or None
|
Alias for |
None
|
freq
|
str
|
Pandas-compatible offset alias for the time bin width. Default: |
'1h'
|
datetime_col
|
str or None
|
Explicit datetime column name. Auto-detected when None. |
None
|
lat_col
|
str or None
|
Explicit latitude column name. Auto-detected when None. |
None
|
lng_col
|
str or None
|
Explicit longitude column name. Auto-detected when None. |
None
|
uid_col
|
str or None
|
Explicit user-ID column name. Auto-detected when None. |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame or DataFrame
|
One row per non-empty time bin with columns
|
Examples:
>>> import pandas as pd
>>> import fastmob
>>> url = fastmob.data.BRIGHTKITE_SAMPLE
>>> df = pd.read_csv(
... url,
... sep="\t",
... header=0,
... nrows=5000,
... names=["uid", "datetime", "lat", "lng", "location id"],
... )
>>> df["datetime"] = pd.to_datetime(df["datetime"], errors="coerce")
>>> df["location_id"] = df["location id"].astype("string")
>>> df = df.dropna(subset=["uid", "datetime", "lat", "lng"])[
... ["uid", "datetime", "lat", "lng", "location_id"]
... ]
>>> print(df.head().to_string(index=False))
uid datetime lat lng location_id
0 2010-10-16 06:02:04+00:00 39.891383 -105.070814 7a0f88982aa015062b95e3b4843f9ca2
0 2010-10-16 03:48:54+00:00 39.891077 -105.068532 dd7cd3d264c2d063832db506fba8bf79
0 2010-10-14 18:25:51+00:00 39.750469 -104.999073 9848afcc62e500a01cf6fbf24b797732f8963683
0 2010-10-14 00:21:47+00:00 39.752713 -104.996337 2ef143e12038c870038df53e0478cefc
0 2010-10-13 23:31:51+00:00 39.752508 -104.996637 424eb3dd143292f9e013efa00486c907
>>> from fastmob import visits_per_time_unit
>>> result = visits_per_time_unit(df)
>>> print(result.head().to_string(index=False))
datetime n_visits
2008-06-21 17:00:00+00:00 1
2008-06-22 01:00:00+00:00 1
2008-06-22 05:00:00+00:00 1
2008-06-22 17:00:00+00:00 1
2008-06-22 18:00:00+00:00 1
References
- [PRS2016] Pappalardo, L., Rinzivillo, S. & Simini, F. (2016) Human Mobility Modelling: exploration and preferential return meet the gravity model. Procedia Computer Science 83, 934-939, http://dx.doi.org/10.1016/j.procs.2016.04.188
fastmob.measures.collective.od_matrix(trips, origin_col=None, destination_col=None)
Compute an Origin-Destination matrix from a trips DataFrame.
Groups trips by (origin, destination) pairs and counts them. Returns a long-format DataFrame with one row per observed origin-destination pair, in the same backend as the input.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
trips
|
DataFrame - like
|
A DataFrame (pandas, polars, or any Narwhals-compatible backend) with at least two columns representing origin and destination areas. |
required |
origin_col
|
str or None
|
Column name for the origin area. Auto-detected if None. |
None
|
destination_col
|
str or None
|
Column name for the destination area. Auto-detected if None. |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame or DataFrame
|
Long-format OD counts with columns
|
Examples:
>>> import pandas as pd
>>> from fastmob.measures.collective import od_matrix
>>> trips = pd.DataFrame(
... {
... "origin_area": ["A", "A", "A", "B", "B", "C"],
... "destination_area": ["A", "B", "B", "A", "C", "A"],
... }
... )
>>> result = od_matrix(trips)
>>> print(result.to_string(index=False))
origin_area destination_area count
A A 1
A B 2
B A 1
B C 1
C A 1
fastmob.measures.collective.od_metrics_per_area(od_df, origin_col=None, destination_col=None)
Compute per-area mobility metrics from a long-format OD DataFrame.
Takes the long-format OD DataFrame returned by :func:od_matrix and
computes MoveInside, InComing, OutGoing, and Total flows for each area.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
od_df
|
DataFrame - like
|
Long-format OD DataFrame as returned by :func: |
required |
origin_col
|
str or None
|
Column name for the origin area. Auto-detected if None. |
None
|
destination_col
|
str or None
|
Column name for the destination area. Auto-detected if None. |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame or DataFrame
|
DataFrame with columns |
Examples:
>>> import pandas as pd
>>> from fastmob.measures.collective import od_matrix, od_metrics_per_area
>>> trips = pd.DataFrame(
... {
... "origin_area": ["A", "A", "A", "B", "B", "C"],
... "destination_area": ["A", "B", "B", "A", "C", "A"],
... }
... )
>>> od = od_matrix(trips)
>>> result = od_metrics_per_area(od)
>>> print(result.to_string(index=False))
area_code MoveInside InComing OutGoing Total
A 1 2 2 5
B 0 2 2 4
C 0 1 1 2
fastmob.measures.collective.mean_area_volume(visits, *, area_col=None, user_id_col=None, start_col=None, end_col=None)
Mean user volume per area and 10-minute time bin, averaged across days of the week.
For each area the function:
- Expands each stay into 10-minute presence slots.
- Counts unique users per slot per calendar date.
- Averages counts over dates for each day-of-week.
- Averages the 7 day-of-week means (missing days contribute 0).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
visits
|
DataFrame - like
|
Any Narwhals-compatible eager dataframe with one row per stay event. |
required |
area_col
|
str or None
|
Area column name. Auto-detected from |
None
|
user_id_col
|
str or None
|
User ID column. Auto-detected from |
None
|
start_col
|
str or None
|
Stay start timestamp. Auto-detected from |
None
|
end_col
|
str or None
|
Stay end timestamp. Auto-detected from |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame or DataFrame
|
Same backend as input. Columns: |
Raises:
| Type | Description |
|---|---|
ValueError
|
If any required column cannot be detected. |
Notes
- A stay where
start == endproduces exactly one bin (the floored start). - A stay where
start > endproduces no bins and is silently skipped. - Stays spanning midnight are handled correctly: bins are attributed to the date on which each bin falls.
Examples:
>>> import pandas as pd
>>> from fastmob.measures.collective import mean_area_volume
>>> visits = pd.DataFrame(
... {
... "user_id": ["u1", "u2", "u1"],
... "area": ["home", "home", "work"],
... "start_timestamp": pd.to_datetime(
... ["2020-01-01 08:00", "2020-01-01 08:10", "2020-01-01 09:00"]
... ),
... "end_timestamp": pd.to_datetime(
... ["2020-01-01 08:20", "2020-01-01 08:20", "2020-01-01 09:10"]
... ),
... }
... )
>>> result = mean_area_volume(visits)
>>> print(result.round({"mean_volume": 3}).to_string(index=False))
area time_bin mean_volume
home 08:00 0.143
home 08:10 0.286
home 08:20 0.286
work 09:00 0.143
work 09:10 0.143
fastmob.measures.collective.build_stvd(staypoints, locations, *, location_id_col='location_id')
Aggregate staypoints against a global Locations catalogue into an STVD frame.
Combines :func:mean_area_volume (per-location, per-time-bin mean visitor volume) with
each location's centroid from locations, producing the (location_id, time_bin,
mean_volume, center_lat, center_lng) shape :func:fastmob.measures.evaluation.stvd_emd
consumes directly. Call this once per side against the same locations catalogue so
the two resulting distributions are defined over the same physical places, then compare
them with stvd_emd.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
staypoints
|
Staypoints or DataFrame - like
|
Staypoints already assigned to |
required |
locations
|
Locations
|
A global-scope |
required |
location_id_col
|
str
|
Column on |
'location_id'
|
Returns:
| Type | Description |
|---|---|
DataFrame - like
|
Same backend as |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Examples:
>>> import pandas as pd
>>> from fastmob.core import Locations, Staypoints
>>> from fastmob.measures.collective import build_stvd
>>> staypoints = Staypoints(
... pd.DataFrame(
... {
... "uid": ["u1", "u2"],
... "lat": [0.0, 0.0],
... "lng": [0.0, 0.0],
... "started_at": pd.to_datetime(["2020-01-01 08:00", "2020-01-01 08:00"]),
... "finished_at": pd.to_datetime(["2020-01-01 08:00", "2020-01-01 08:00"]),
... "location_id": [1, 1],
... }
... )
... )
>>> locations = Locations(
... pd.DataFrame({"location_id": [1], "center_lat": [0.0], "center_lng": [0.0]}),
... scope="global",
... )
>>> build_stvd(staypoints, locations)
location_id time_bin mean_volume center_lat center_lng
0 1 08:00 0.285714 0.0 0.0