librosa.util.match_intervals¶
- librosa.util.match_intervals(intervals_from, intervals_to, strict=True)[source]¶
Match one set of time intervals to another.
This can be useful for tasks such as mapping beat timings to segments.
Each element
[a, b]
ofintervals_from
is matched to the element[c, d]
ofintervals_to
which maximizes the Jaccard similarity between the intervals:max(0, |min(b, d) - max(a, c)|) / |max(d, b) - min(a, c)|
In
strict=True
mode, if there is no interval with positive intersection with[a,b]
, an exception is thrown.In
strict=False
mode, any interval[a, b]
that has no intersection with any element ofintervals_to
is instead matched to the interval[c, d]
which minimizes:min(|b - c|, |a - d|)
that is, the disjoint interval [c, d] with a boundary closest to [a, b].
Note
An element of
intervals_to
may be matched to multiple entries ofintervals_from
.- Parameters
- intervals_fromnp.ndarray [shape=(n, 2)]
The time range for source intervals. The
i
th interval spans timeintervals_from[i, 0]
tointervals_from[i, 1]
.intervals_from[0, 0]
should be 0,intervals_from[-1, 1]
should be the track duration.- intervals_tonp.ndarray [shape=(m, 2)]
Analogous to
intervals_from
.- strictbool
If
True
, intervals can only match if they intersect. IfFalse
, disjoint intervals can match.
- Returns
- interval_mappingnp.ndarray [shape=(n,)]
For each interval in
intervals_from
, the corresponding interval inintervals_to
.
- Raises
- ParameterError
If either array of input intervals is not the correct shape
If
strict=True
and some element ofintervals_from
is disjoint from every element ofintervals_to
.
See also
Examples
>>> ints_from = np.array([[3, 5], [1, 4], [4, 5]]) >>> ints_to = np.array([[0, 2], [1, 3], [4, 5], [6, 7]]) >>> librosa.util.match_intervals(ints_from, ints_to) array([2, 1, 2], dtype=uint32) >>> # [3, 5] => [4, 5] (ints_to[2]) >>> # [1, 4] => [1, 3] (ints_to[1]) >>> # [4, 5] => [4, 5] (ints_to[2])
The reverse matching of the above is not possible in
strict
mode because[6, 7]
is disjoint from all intervals inints_from
. Withstrict=False
, we get the following:>>> librosa.util.match_intervals(ints_to, ints_from, strict=False) array([1, 1, 2, 2], dtype=uint32) >>> # [0, 2] => [1, 4] (ints_from[1]) >>> # [1, 3] => [1, 4] (ints_from[1]) >>> # [4, 5] => [4, 5] (ints_from[2]) >>> # [6, 7] => [4, 5] (ints_from[2])