Reference¶
Data structures¶
Segment¶
-
class
pyannote.core.
Segment
(start: float = 0.0, end: float = 0.0)[source]¶ Time interval
- Parameters:
Segments can be compared and sorted using the standard operators:
>>> Segment(0, 1) == Segment(0, 1.) True >>> Segment(0, 1) != Segment(3, 4) True >>> Segment(0, 1) < Segment(2, 3) True >>> Segment(0, 1) < Segment(0, 2) True >>> Segment(1, 2) < Segment(0, 3) False
Note
A segment is smaller than another segment if one of these two conditions is verified:
segment.start < other_segment.start
segment.start == other_segment.start and segment.end < other_segment.end
-
__and__
(other)[source]¶ Intersection
>>> segment = Segment(0, 10) >>> other_segment = Segment(5, 15) >>> segment & other_segment <Segment(5, 10)>
Note
When the intersection is empty, an empty segment is returned:
>>> segment = Segment(0, 10) >>> other_segment = Segment(15, 20) >>> intersection = segment & other_segment >>> if not intersection: ... # intersection is empty.
-
__bool__
()[source]¶ Emptiness
>>> if segment: ... # segment is not empty. ... else: ... # segment is empty.
Note
A segment is considered empty if its end time is smaller than its start time, or its duration is smaller than 1μs.
-
__contains__
(other: pyannote.core.segment.Segment)[source]¶ Inclusion
>>> segment = Segment(start=0, end=10) >>> Segment(start=3, end=10) in segment: True >>> Segment(start=5, end=15) in segment: False
-
__iter__
() → Iterator[float][source]¶ Unpack segment boundaries >>> segment = Segment(start, end) >>> start, end = segment
-
__or__
(other: pyannote.core.segment.Segment) → pyannote.core.segment.Segment[source]¶ Union
>>> segment = Segment(0, 10) >>> other_segment = Segment(5, 15) >>> segment | other_segment <Segment(0, 15)>
Note
When a gap exists between the segment, their union covers the gap as well:
>>> segment = Segment(0, 10) >>> other_segment = Segment(15, 20) >>> segment | other_segment <Segment(0, 20)
-
__repr__
()[source]¶ Computer-readable representation
>>> Segment(1337, 1337 + 0.42) <Segment(1337, 1337.42)>
-
__str__
()[source]¶ Human-readable representation
>>> print(Segment(1337, 1337 + 0.42)) [ 00:22:17.000 --> 00:22:17.420]
Note
Empty segments are printed as “[]”
-
__weakref__
¶ list of weak references to the object (if defined)
-
__xor__
(other: pyannote.core.segment.Segment) → pyannote.core.segment.Segment[source]¶ Gap
>>> segment = Segment(0, 10) >>> other_segment = Segment(15, 20) >>> segment ^ other_segment <Segment(10, 15)
Note
The gap between a segment and an empty segment is not defined.
>>> segment = Segment(0, 10) >>> empty_segment = Segment(11, 11) >>> segment ^ empty_segment ValueError: The gap between a segment and an empty segment is not defined.
-
copy
() → pyannote.core.segment.Segment[source]¶ Get a copy of the segment
- Returns:
copy – Copy of the segment.
- Return type:
-
property
duration
¶ Segment duration (read-only)
-
for_json
()[source]¶ Serialization
See also
-
classmethod
from_json
(data)[source]¶ Deserialization
See also
-
intersects
(other: pyannote.core.segment.Segment) → bool[source]¶ Check whether two segments intersect each other
-
property
middle
¶ Segment mid-time (read-only)
-
static
set_precision
(ndigits: Optional[int] = None)[source]¶ Automatically round start and end timestamps to ndigits precision after the decimal point
To ensure consistency between Segment instances, it is recommended to call this method only once, right after importing pyannote.core.Segment.
>>> from pyannote.core import Segment >>> Segment.set_precision(2) >>> Segment(1/3, 2/3) <Segment(0.33, 0.67)>
Timeline¶
-
class
pyannote.core.
Timeline
(segments: Optional[Iterable[pyannote.core.segment.Segment]] = None, uri: str = None)[source]¶ Ordered set of segments.
A timeline can be seen as an ordered set of non-empty segments (Segment). Segments can overlap – though adding an already exisiting segment to a timeline does nothing.
- Parameters:
segments (Segment iterator, optional) – initial set of (non-empty) segments
uri (string, optional) – name of segmented resource
- Returns:
timeline – New timeline
- Return type:
-
__bool__
()[source]¶ Emptiness
>>> if timeline: ... # timeline is not empty ... else: ... # timeline is empty
-
__contains__
(included: Union[pyannote.core.segment.Segment, Timeline])[source]¶ Inclusion
Check whether every segment of included does exist in timeline.
- Parameters:
included (Segment or Timeline) – Segment or timeline being checked for inclusion
- Returns:
contains – True if every segment in included exists in timeline, False otherwise
- Return type:
Examples
>>> timeline1 = Timeline(segments=[Segment(0, 10), Segment(1, 13.37)]) >>> timeline2 = Timeline(segments=[Segment(0, 10)]) >>> timeline1 in timeline2 False >>> timeline2 in timeline1 >>> Segment(1, 13.37) in timeline1 True
-
__eq__
(other: pyannote.core.timeline.Timeline)[source]¶ Equality
Two timelines are equal if and only if their segments are equal.
>>> timeline1 = Timeline([Segment(0, 1), Segment(2, 3)]) >>> timeline2 = Timeline([Segment(2, 3), Segment(0, 1)]) >>> timeline3 = Timeline([Segment(2, 3)]) >>> timeline1 == timeline2 True >>> timeline1 == timeline3 False
-
__getitem__
(k: int) → pyannote.core.segment.Segment[source]¶ Get segment by index (in chronological order)
>>> first_segment = timeline[0] >>> penultimate_segment = timeline[-2]
-
__init__
(segments: Optional[Iterable[pyannote.core.segment.Segment]] = None, uri: str = None)[source]¶ Initialize self. See help(type(self)) for accurate signature.
-
__iter__
() → Iterable[pyannote.core.segment.Segment][source]¶ Iterate over segments (in chronological order)
>>> for segment in timeline: ... # do something with the segment
See also
-
__repr__
()[source]¶ Computer-readable representation
>>> Timeline(segments=[Segment(0, 10), Segment(1, 13.37)]) <Timeline(uri=None, segments=[<Segment(0, 10)>, <Segment(1, 13.37)>])>
-
__str__
()[source]¶ Human-readable representation
>>> timeline = Timeline(segments=[Segment(0, 10), Segment(1, 13.37)]) >>> print(timeline) [[ 00:00:00.000 --> 00:00:10.000] [ 00:00:01.000 --> 00:00:13.370]]
-
__weakref__
¶ list of weak references to the object (if defined)
-
add
(segment: pyannote.core.segment.Segment) → pyannote.core.timeline.Timeline[source]¶ Add a segment (in place)
- Parameters:
segment (Segment) – Segment that is being added
- Returns:
self – Updated timeline.
- Return type:
Note
If the timeline already contains this segment, it will not be added again, as a timeline is meant to be a set of segments (not a list).
If the segment is empty, it will not be added either, as a timeline only contains non-empty segments.
-
co_iter
(other: pyannote.core.timeline.Timeline) → Iterator[Tuple[pyannote.core.segment.Segment, pyannote.core.segment.Segment]][source]¶ Iterate over pairs of intersecting segments
>>> timeline1 = Timeline([Segment(0, 2), Segment(1, 2), Segment(3, 4)]) >>> timeline2 = Timeline([Segment(1, 3), Segment(3, 5)]) >>> for segment1, segment2 in timeline1.co_iter(timeline2): ... print(segment1, segment2) (<Segment(0, 2)>, <Segment(1, 3)>) (<Segment(1, 2)>, <Segment(1, 3)>) (<Segment(3, 4)>, <Segment(3, 5)>)
-
copy
(segment_func: Optional[Callable[[pyannote.core.segment.Segment], pyannote.core.segment.Segment]] = None) → pyannote.core.timeline.Timeline[source]¶ Get a copy of the timeline
If segment_func is provided, it is applied to each segment first.
- Parameters:
segment_func (callable, optional) – Callable that takes a segment as input, and returns a segment. Defaults to identity function (segment_func(segment) = segment)
- Returns:
timeline – Copy of the timeline
- Return type:
-
covers
(other: pyannote.core.timeline.Timeline) → bool[source]¶ Check whether other timeline is fully covered by the timeline
- otherTimeline
Second timeline
- Returns:
covers – True if timeline covers “other” timeline entirely. False if at least one segment of “other” is not fully covered by timeline
- Return type:
-
crop
(support: Union[Segment, Timeline], mode: typing_extensions.Literal['intersection', 'loose', 'strict'][intersection, loose, strict] = 'intersection', returns_mapping: bool = False) → Union[pyannote.core.timeline.Timeline, Tuple[pyannote.core.timeline.Timeline, Dict[pyannote.core.segment.Segment, pyannote.core.segment.Segment]]][source]¶ Crop timeline to new support
- Parameters:
support (Segment or Timeline) – If support is a Timeline, its support is used.
mode ({'strict', 'loose', 'intersection'}, optional) – Controls how segments that are not fully included in support are handled. ‘strict’ mode only keeps fully included segments. ‘loose’ mode keeps any intersecting segment. ‘intersection’ mode keeps any intersecting segment but replace them by their actual intersection.
returns_mapping (bool, optional) – In ‘intersection’ mode, return a dictionary whose keys are segments of the cropped timeline, and values are list of the original segments that were cropped. Defaults to False.
- Returns:
cropped (Timeline) – Cropped timeline
mapping (dict) – When ‘returns_mapping’ is True, dictionary whose keys are segments of ‘cropped’, and values are lists of corresponding original segments.
Examples
>>> timeline = Timeline([Segment(0, 2), Segment(1, 2), Segment(3, 4)]) >>> timeline.crop(Segment(1, 3)) <Timeline(uri=None, segments=[<Segment(1, 2)>])>
>>> timeline.crop(Segment(1, 3), mode='loose') <Timeline(uri=None, segments=[<Segment(0, 2)>, <Segment(1, 2)>])>
>>> timeline.crop(Segment(1, 3), mode='strict') <Timeline(uri=None, segments=[<Segment(1, 2)>])>
>>> cropped, mapping = timeline.crop(Segment(1, 3), returns_mapping=True) >>> print(mapping) {<Segment(1, 2)>: [<Segment(0, 2)>, <Segment(1, 2)>]}
-
crop_iter
(support: Union[Segment, Timeline], mode: typing_extensions.Literal['intersection', 'loose', 'strict'][intersection, loose, strict] = 'intersection', returns_mapping: bool = False) → Iterator[Union[Tuple[pyannote.core.segment.Segment, pyannote.core.segment.Segment], pyannote.core.segment.Segment]][source]¶ Like crop but returns a segment iterator instead
See also
-
discard
(segment: pyannote.core.segment.Segment) → pyannote.core.timeline.Timeline[source]¶ Same as remove
See also
pyannote.core.Timeline.remove()
-
duration
() → float[source]¶ Timeline duration
The timeline duration is the sum of the durations of the segments in the timeline support.
- Returns:
duration – Duration of timeline support, in seconds.
- Return type:
-
empty
() → pyannote.core.timeline.Timeline[source]¶ Return an empty copy
- Returns:
empty – Empty timeline using the same ‘uri’ attribute.
- Return type:
-
extent
() → pyannote.core.segment.Segment[source]¶ Extent
The extent of a timeline is the segment of minimum duration that contains every segments of the timeline. It is unique, by definition. The extent of an empty timeline is an empty segment.
A picture is worth a thousand words:
timeline |------| |------| |----| |--| |-----| |----------| timeline.extent() |--------------------------------|
- Returns:
extent – Timeline extent
- Return type:
Examples
>>> timeline = Timeline(segments=[Segment(0, 1), Segment(9, 10)]) >>> timeline.extent() <Segment(0, 10)>
-
extrude
(removed: Union[Segment, Timeline], mode: typing_extensions.Literal['intersection', 'loose', 'strict'][intersection, loose, strict] = 'intersection') → pyannote.core.timeline.Timeline[source]¶ Remove segments that overlap removed support.
- Parameters:
removed (Segment or Timeline) – If support is a Timeline, its support is used.
mode ({'strict', 'loose', 'intersection'}, optional) – Controls how segments that are not fully included in removed are handled. ‘strict’ mode only removes fully included segments. ‘loose’ mode removes any intersecting segment. ‘intersection’ mode removes the overlapping part of any intersecting segment.
- Returns:
extruded – Extruded timeline
- Return type:
Examples
>>> timeline = Timeline([Segment(0, 2), Segment(1, 2), Segment(3, 5)]) >>> timeline.extrude(Segment(1, 2)) <Timeline(uri=None, segments=[<Segment(0, 1)>, <Segment(3, 5)>])>
>>> timeline.extrude(Segment(1, 3), mode='loose') <Timeline(uri=None, segments=[<Segment(3, 5)>])>
>>> timeline.extrude(Segment(1, 3), mode='strict') <Timeline(uri=None, segments=[<Segment(0, 2)>, <Segment(3, 5)>])>
-
for_json
()[source]¶ Serialization
See also
-
classmethod
from_json
(data)[source]¶ Deserialization
See also
-
gaps
(support: Union[Segment, Timeline, None] = None) → pyannote.core.timeline.Timeline[source]¶ Gaps
A picture is worth a thousand words:
timeline |------| |------| |----| |--| |-----| |----------| timeline.gaps() |--| |--|
- Parameters:
support (None, Segment or Timeline) – Support in which gaps are looked for. Defaults to timeline extent
- Returns:
gaps – Timeline made of all gaps from original timeline, and delimited by provided support
- Return type:
See also
pyannote.core.Timeline.extent()
-
gaps_iter
(support: Union[Segment, Timeline, None] = None) → Iterator[pyannote.core.segment.Segment][source]¶ Like gaps but returns a segment generator instead
See also
-
get_overlap
() → pyannote.core.timeline.Timeline[source]¶ Get overlapping parts of the timeline.
- Returns:
overlap – Timeline of the overlaps.
- Return type:
pyannote.core.Timeline
-
overlapping
(t: float) → List[pyannote.core.segment.Segment][source]¶ Get list of segments overlapping t
-
overlapping_iter
(t: float) → Iterator[pyannote.core.segment.Segment][source]¶ Like overlapping but returns a segment iterator instead
See also
pyannote.core.Timeline.overlapping()
-
remove
(segment: pyannote.core.segment.Segment) → pyannote.core.timeline.Timeline[source]¶ Remove a segment (in place)
- Parameters:
segment (Segment) – Segment that is being removed
- Returns:
self – Updated timeline.
- Return type:
Note
If the timeline does not contain this segment, this does nothing
-
segmentation
() → pyannote.core.timeline.Timeline[source]¶ Segmentation
Create the unique timeline with same support and same set of segment boundaries as original timeline, but with no overlapping segments.
A picture is worth a thousand words:
timeline |------| |------| |----| |--| |-----| |----------| timeline.segmentation() |-|--|-| |-|---|--| |--|----|--|
- Returns:
timeline – (unique) timeline with same support and same set of segment boundaries as original timeline, but with no overlapping segments.
- Return type:
-
support
(collar: float = 0.0) → pyannote.core.timeline.Timeline[source]¶ Timeline support
The support of a timeline is the timeline with the minimum number of segments with exactly the same time span as the original timeline. It is (by definition) unique and does not contain any overlapping segments.
A picture is worth a thousand words:
collar |---| timeline |------| |------| |----| |--| |-----| |----------| timeline.support() |------| |--------| |----------| timeline.support(collar) |------------------| |----------|
-
support_iter
(collar: float = 0.0) → Iterator[pyannote.core.segment.Segment][source]¶ Like support but returns a segment generator instead
See also
pyannote.core.Timeline.support()
-
to_annotation
(generator: Union[str, Iterable[Hashable], None] = 'string', modality: Optional[str] = None) → Annotation[source]¶ Turn timeline into an annotation
Each segment is labeled by a unique label.
- Parameters:
generator ('string', 'int', or iterable, optional) – If ‘string’ (default) generate string labels. If ‘int’, generate integer labels. If iterable, use it to generate labels.
modality (str, optional) –
- Returns:
annotation – Annotation
- Return type:
-
union
(timeline: pyannote.core.timeline.Timeline) → pyannote.core.timeline.Timeline[source]¶ Create new timeline made of union of segments
- Parameters:
timeline (Timeline) – Timeline whose segments are being added
- Returns:
union – New timeline containing the union of both timelines.
- Return type:
Note
This does the same as timeline.update(…) except it returns a new timeline, and the original one is not modified.
-
update
(timeline: pyannote.core.segment.Segment) → pyannote.core.timeline.Timeline[source]¶ Add every segments of an existing timeline (in place)
- Parameters:
timeline (Timeline) – Timeline whose segments are being added
- Returns:
self – Updated timeline
- Return type:
Note
Only segments that do not already exist will be added, as a timeline is meant to be a set of segments (not a list).
-
write_uem
(file: TextIO)[source]¶ Dump timeline to file using UEM format
- Parameters:
file (file object) –
Usage –
----- –
with open('file.uem', 'w') as file (>>>) –
timeline.write_uem(file) (..) –
Annotation¶
-
class
pyannote.core.
Annotation
(uri: Optional[str] = None, modality: Optional[str] = None)[source]¶ - Parameters:
uri (string, optional) – name of annotated resource (e.g. audio or video file)
modality (string, optional) – name of annotated modality
- Returns:
annotation – New annotation
- Return type:
-
__bool__
()[source]¶ Emptiness
>>> if annotation: ... # annotation is not empty ... else: ... # annotation is empty
-
__contains__
(included: Union[pyannote.core.segment.Segment, pyannote.core.timeline.Timeline])[source]¶ Inclusion
Check whether every segment of included does exist in annotation.
-
__delitem__
(key: Union[Segment, Tuple[Segment, Union[str, int]]])[source]¶ Delete one track
>>> del annotation[segment, track]
Delete all tracks of a segment
>>> del annotation[segment]
-
__eq__
(other: pyannote.core.annotation.Annotation)[source]¶ Equality
>>> annotation == other
Two annotations are equal if and only if their tracks and associated labels are equal.
-
__getitem__
(key: Union[Segment, Tuple[Segment, Union[str, int]]]) → Hashable[source]¶ Get track label
>>> label = annotation[segment, track]
Note
annotation[segment]
is equivalent toannotation[segment, '_']
-
__init__
(uri: Optional[str] = None, modality: Optional[str] = None)[source]¶ Initialize self. See help(type(self)) for accurate signature.
-
__mul__
(other: pyannote.core.annotation.Annotation) → numpy.ndarray[source]¶ Cooccurrence (or confusion) matrix
>>> matrix = annotation * other
- Parameters:
other (Annotation) – Second annotation
- Returns:
cooccurrence – Cooccurrence matrix where n_self (resp. n_other) is the number of labels in self (resp. other).
- Return type:
(n_self, n_other) np.ndarray
-
__setitem__
(key: Union[Segment, Tuple[Segment, Union[str, int]]], label: Hashable)[source]¶ Add new or update existing track
>>> annotation[segment, track] = label
If (segment, track) does not exist, it is added. If (segment, track) already exists, it is updated.
Note
annotation[segment] = label
is equivalent toannotation[segment, '_'] = label
Note
If segment is empty, it does nothing.
-
__weakref__
¶ list of weak references to the object (if defined)
-
argmax
(support: Union[Segment, Timeline, None] = None) → Optional[Hashable][source]¶ Get label with longest duration
- Parameters:
support (Segment or Timeline, optional) – Find label with longest duration within provided support. Defaults to whole extent.
- Returns:
label – Label with longest intersection
- Return type:
any existing label or None
Examples
>>> annotation = Annotation(modality='speaker') >>> annotation[Segment(0, 10), 'speaker1'] = 'Alice' >>> annotation[Segment(8, 20), 'speaker1'] = 'Bob' >>> print "%s is such a talker!" % annotation.argmax() Bob is such a talker! >>> segment = Segment(22, 23) >>> if not annotation.argmax(support): ... print "No label intersecting %s" % segment No label intersection [22 --> 23]
-
chart
(percent: bool = False) → List[Tuple[Hashable, float]][source]¶ Get labels chart (from longest to shortest duration)
-
co_iter
(other: pyannote.core.annotation.Annotation) → Iterator[Tuple[Tuple[pyannote.core.segment.Segment, Union[str, int]], Tuple[pyannote.core.segment.Segment, Union[str, int]]]][source]¶ Iterate over pairs of intersecting tracks
- Parameters:
other (Annotation) – Second annotation
- Returns:
iterable – Yields pairs of intersecting tracks, in chronological (then alphabetical) order.
- Return type:
See also
-
copy
() → pyannote.core.annotation.Annotation[source]¶ Get a copy of the annotation
- Returns:
annotation – Copy of the annotation
- Return type:
-
crop
(support: Union[Segment, Timeline], mode: typing_extensions.Literal['intersection', 'loose', 'strict'][intersection, loose, strict] = 'intersection') → pyannote.core.annotation.Annotation[source]¶ Crop annotation to new support
- Parameters:
support (Segment or Timeline) – If support is a Timeline, its support is used.
mode ({'strict', 'loose', 'intersection'}, optional) – Controls how segments that are not fully included in support are handled. ‘strict’ mode only keeps fully included segments. ‘loose’ mode keeps any intersecting segment. ‘intersection’ mode keeps any intersecting segment but replace them by their actual intersection.
- Returns:
cropped – Cropped annotation
- Return type:
Note
In ‘intersection’ mode, the best is done to keep the track names unchanged. However, in some cases where two original segments are cropped into the same resulting segments, conflicting track names are modified to make sure no track is lost.
-
discretize
(support: Optional[pyannote.core.segment.Segment] = None, resolution: Union[float, pyannote.core.segment.SlidingWindow] = 0.01, labels: Optional[List[Hashable]] = None, duration: Optional[float] = None)[source]¶ Discretize
- Parameters:
support (Segment, optional) – Part of annotation to discretize. Defaults to annotation full extent.
resolution (float or SlidingWindow, optional) – Defaults to 10ms frames.
labels (list of labels, optional) – Defaults to self.labels()
duration (float, optional) – Overrides support duration and ensures that the number of returned frames is fixed (which might otherwise not be the case because of rounding errors).
- Returns:
discretized – (num_frames, num_labels)-shaped binary features.
- Return type:
-
empty
() → pyannote.core.annotation.Annotation[source]¶ Return an empty copy
- Returns:
empty – Empty annotation using the same ‘uri’ and ‘modality’ attributes.
- Return type:
-
extrude
(removed: Union[Segment, Timeline], mode: typing_extensions.Literal['intersection', 'loose', 'strict'][intersection, loose, strict] = 'intersection') → pyannote.core.annotation.Annotation[source]¶ Remove segments that overlap removed support.
A simple illustration:
annotation A |------| |------| B |----------| C |--------------| |------|
- removed Timeline
extruded Annotation with mode=”intersection” B |---| C |--| |------|
extruded Annotation with mode=”loose” C |------|
extruded Annotation with mode=”strict” A |------| B |----------| C |--------------| |------|
- Parameters:
removed (Segment or Timeline) – If support is a Timeline, its support is used.
mode ({'strict', 'loose', 'intersection'}, optional) – Controls how segments that are not fully included in removed are handled. ‘strict’ mode only removes fully included segments. ‘loose’ mode removes any intersecting segment. ‘intersection’ mode removes the overlapping part of any intersecting segment.
- Returns:
extruded – Extruded annotation
- Return type:
Note
In ‘intersection’ mode, the best is done to keep the track names unchanged. However, in some cases where two original segments are cropped into the same resulting segments, conflicting track names are modified to make sure no track is lost.
-
for_json
() → Dict[source]¶ Serialization
See also
-
classmethod
from_json
(data: Dict) → pyannote.core.annotation.Annotation[source]¶ Deserialization
See also
-
classmethod
from_records
(records: Iterator[Tuple[pyannote.core.segment.Segment, Union[str, int], Hashable]], uri: Optional[str] = None, modality: Optional[str] = None) → pyannote.core.annotation.Annotation[source]¶ Annotation
- Parameters:
records (iterator of tuples) – (segment, track, label) tuples
uri (string, optional) – name of annotated resource (e.g. audio or video file)
modality (string, optional) – name of annotated modality
- Returns:
annotation – New annotation
- Return type:
-
get_labels
(segment: pyannote.core.segment.Segment, unique: bool = True) → Union[Set[Hashable], List[Hashable]][source]¶ Query labels by segment
- Parameters:
- Returns:
labels – Set (resp. list) of labels for segment if it exists, empty set (resp. list) otherwise if unique (resp. if not unique).
- Return type:
Examples
>>> annotation = Annotation() >>> segment = Segment(0, 2) >>> annotation[segment, 'speaker1'] = 'Bernard' >>> annotation[segment, 'speaker2'] = 'John' >>> print sorted(annotation.get_labels(segment)) set(['Bernard', 'John']) >>> print annotation.get_labels(Segment(1, 2)) set([])
-
get_overlap
(labels: Optional[Iterable[Hashable]] = None) → pyannote.core.timeline.Timeline[source]¶ Get overlapping parts of the annotation.
A simple illustration:
annotation A |------| |------| |----| B |--| |-----| |----------| C |--------------| |------|
- Parameters:
labels (optional list of labels) – Labels for which to consider the overlap
- Returns:
overlap – Timeline of the overlaps.
- Return type:
pyannote.core.Timeline
-
get_timeline
(copy: bool = True) → pyannote.core.timeline.Timeline[source]¶ Get timeline made of all annotated segments
- Parameters:
copy (bool, optional) – Defaults (True) to returning a copy of the internal timeline. Set to False to return the actual internal timeline (faster).
- Returns:
timeline – Timeline made of all annotated segments.
- Return type:
Note
In case copy is set to False, be careful not to modify the returned timeline, as it may lead to weird subsequent behavior of the annotation instance.
-
get_tracks
(segment: pyannote.core.segment.Segment) → Set[Union[str, int]][source]¶ Query tracks by segment
Note
This will return an empty set if segment does not exist.
-
has_track
(segment: pyannote.core.segment.Segment, track: Union[str, int]) → bool[source]¶ Check whether a given track exists
-
itersegments
()[source]¶ Iterate over segments (in chronological order)
>>> for segment in annotation.itersegments(): ... # do something with the segment
See also
-
itertracks
(yield_label: bool = False) → Iterator[Union[Tuple[pyannote.core.segment.Segment, Union[str, int]], Tuple[pyannote.core.segment.Segment, Union[str, int], Hashable]]][source]¶ Iterate over tracks (in chronological order)
- Parameters:
yield_label (bool, optional) – When True, yield (segment, track, label) tuples, such that annotation[segment, track] == label. Defaults to yielding (segment, track) tuple.
Examples
>>> for segment, track in annotation.itertracks(): ... # do something with the track
>>> for segment, track, label in annotation.itertracks(yield_label=True): ... # do something with the track and its label
-
label_duration
(label: Hashable) → float[source]¶ Label duration
Equivalent to
Annotation.label_timeline(label).duration()
See also
-
label_support
(label: Hashable) → pyannote.core.timeline.Timeline[source]¶ Label support
Equivalent to
Annotation.label_timeline(label).support()
See also
-
label_timeline
(label: Hashable, copy: bool = True) → pyannote.core.timeline.Timeline[source]¶ Query segments by label
- Parameters:
- Returns:
timeline – Timeline made of all segments for which at least one track is annotated as label
- Return type:
Note
If label does not exist, this will return an empty timeline.
Note
In case copy is set to False, be careful not to modify the returned timeline, as it may lead to weird subsequent behavior of the annotation instance.
-
labels
() → List[Hashable][source]¶ Get sorted list of labels
- Returns:
labels – Sorted list of labels
- Return type:
-
new_track
(segment: pyannote.core.segment.Segment, candidate: Union[str, int, None] = None, prefix: Optional[str] = None) → Union[str, int][source]¶ Generate a new track name for given segment
Ensures that the returned track name does not already exist for the given segment.
-
relabel_tracks
(generator: Union[typing_extensions.Literal['int', 'string'][int, string], Iterator[Hashable]] = 'string') → pyannote.core.annotation.Annotation[source]¶ Relabel tracks
Create a new annotation where each track has a unique label.
- Parameters:
generator ('string', 'int' or iterable, optional) – If ‘string’ (default) relabel tracks to ‘A’, ‘B’, ‘C’, … If ‘int’ relabel to 0, 1, 2, … If iterable, use it to generate labels.
- Returns:
renamed – New annotation with relabeled tracks.
- Return type:
-
rename_labels
(mapping: Optional[Dict] = None, generator: Union[typing_extensions.Literal['int', 'string'][int, string], Iterator[Hashable]] = 'string', copy: bool = True) → pyannote.core.annotation.Annotation[source]¶ Rename labels
- Parameters:
mapping (dict, optional) – {old_name: new_name} mapping dictionary.
generator ('string', 'int' or iterable, optional) – If ‘string’ (default) rename label to ‘A’, ‘B’, ‘C’, … If ‘int’, rename to 0, 1, 2, etc. If iterable, use it to generate labels.
copy (bool, optional) – Set to True to return a copy of the annotation. Set to False to update the annotation in-place. Defaults to True.
- Returns:
renamed – Annotation where labels have been renamed
- Return type:
Note
Unmapped labels are kept unchanged.
Note
Parameter generator has no effect when mapping is provided.
-
rename_tracks
(generator: Union[typing_extensions.Literal['int', 'string'][int, string], Iterator[Hashable]] = 'string') → pyannote.core.annotation.Annotation[source]¶ Rename all tracks
- Parameters:
generator ('string', 'int', or iterable, optional) – If ‘string’ (default) rename tracks to ‘A’, ‘B’, ‘C’, etc. If ‘int’, rename tracks to 0, 1, 2, etc. If iterable, use it to generate track names.
- Returns:
renamed – Copy of the original annotation where tracks are renamed.
- Return type:
Example
>>> annotation = Annotation() >>> annotation[Segment(0, 1), 'a'] = 'a' >>> annotation[Segment(0, 1), 'b'] = 'b' >>> annotation[Segment(1, 2), 'a'] = 'a' >>> annotation[Segment(1, 3), 'c'] = 'c' >>> print(annotation) [ 00:00:00.000 --> 00:00:01.000] a a [ 00:00:00.000 --> 00:00:01.000] b b [ 00:00:01.000 --> 00:00:02.000] a a [ 00:00:01.000 --> 00:00:03.000] c c >>> print(annotation.rename_tracks(generator='int')) [ 00:00:00.000 --> 00:00:01.000] 0 a [ 00:00:00.000 --> 00:00:01.000] 1 b [ 00:00:01.000 --> 00:00:02.000] 2 a [ 00:00:01.000 --> 00:00:03.000] 3 c
-
subset
(labels: Iterable[Hashable], invert: bool = False) → pyannote.core.annotation.Annotation[source]¶ Filter annotation by labels
- Parameters:
labels (iterable) – List of filtered labels
invert (bool, optional) – If invert is True, extract all but requested labels
- Returns:
filtered – Filtered annotation
- Return type:
-
support
(collar: float = 0.0) → pyannote.core.annotation.Annotation[source]¶ Annotation support
The support of an annotation is an annotation where contiguous tracks with same label are merged into one unique covering track.
A picture is worth a thousand words:
collar |---| annotation |--A--| |--A--| |-B-| |-B-| |--C--| |----B-----| annotation.support(collar) |------A------| |------B------| |-B-| |--C--|
- Parameters:
collar (float, optional) – Merge tracks with same label and separated by less than collar seconds. This is why ‘A’ tracks are merged in above figure. Defaults to 0.
- Returns:
support – Annotation support
- Return type:
Note
Track names are lost in the process.
-
update
(annotation: pyannote.core.annotation.Annotation, copy: bool = False) → pyannote.core.annotation.Annotation[source]¶ Add every track of an existing annotation (in place)
- Parameters:
annotation (Annotation) – Annotation whose tracks are being added
copy (bool, optional) – Return a copy of the annotation. Defaults to updating the annotation in-place.
- Returns:
self – Updated annotation
- Return type:
Note
Existing tracks are updated with the new label.
-
write_rttm
(file: TextIO)[source]¶ Dump annotation to file using RTTM format
- Parameters:
file (file object) –
Usage –
----- –
with open('file.rttm', 'w') as file (>>>) –
annotation.write_rttm(file) (..) –
SlidingWindow¶
-
class
pyannote.core.
SlidingWindow
(duration=0.03, step=0.01, start=0.0, end=None)[source]¶ Sliding window
- Parameters:
duration (float > 0, optional) – Window duration, in seconds. Default is 30 ms.
step (float > 0, optional) – Step between two consecutive position, in seconds. Default is 10 ms.
start (float, optional) – First start position of window, in seconds. Default is 0.
end (float > start, optional) – Default is infinity (ie. window keeps sliding forever)
Examples
>>> sw = SlidingWindow(duration, step, start) >>> frame_range = (a, b) >>> frame_range == sw.toFrameRange(sw.toSegment(*frame_range)) ... True
>>> segment = Segment(A, B) >>> new_segment = sw.toSegment(*sw.toFrameRange(segment)) >>> abs(segment) - abs(segment & new_segment) < .5 * sw.step
>>> sw = SlidingWindow(end=0.1) >>> print(next(sw)) [ 00:00:00.000 --> 00:00:00.030] >>> print(next(sw)) [ 00:00:00.010 --> 00:00:00.040]
-
__call__
(support: Union[pyannote.core.segment.Segment, Timeline], align_last: bool = False) → Iterable[pyannote.core.segment.Segment][source]¶ Slide window over support
- supportSegment or Timeline
Support on which to slide the window.
- align_lastbool, optional
Yield a final segment so that it aligns exactly with end of support.
- Yields:
chunk (Segment)
Example
>>> window = SlidingWindow(duration=2., step=1.) >>> for chunk in window(Segment(3, 7.5)): ... print(tuple(chunk)) (3.0, 5.0) (4.0, 6.0) (5.0, 7.0) >>> for chunk in window(Segment(3, 7.5), align_last=True): ... print(tuple(chunk)) (3.0, 5.0) (4.0, 6.0) (5.0, 7.0) (5.5, 7.5)
-
__init__
(duration=0.03, step=0.01, start=0.0, end=None)[source]¶ Initialize self. See help(type(self)) for accurate signature.
-
__iter__
() → pyannote.core.segment.SlidingWindow[source]¶ Sliding window iterator
Use expression ‘for segment in sliding_window’
Examples
>>> window = SlidingWindow(end=0.1) >>> for segment in window: ... print(segment) [ 00:00:00.000 --> 00:00:00.030] [ 00:00:00.010 --> 00:00:00.040] [ 00:00:00.020 --> 00:00:00.050] [ 00:00:00.030 --> 00:00:00.060] [ 00:00:00.040 --> 00:00:00.070] [ 00:00:00.050 --> 00:00:00.080] [ 00:00:00.060 --> 00:00:00.090] [ 00:00:00.070 --> 00:00:00.100] [ 00:00:00.080 --> 00:00:00.110] [ 00:00:00.090 --> 00:00:00.120]
-
__len__
() → int[source]¶ Number of positions
Equivalent to len([segment for segment in window])
- Returns:
length – Number of positions taken by the sliding window (from start times to end times)
- Return type:
-
__weakref__
¶ list of weak references to the object (if defined)
-
crop
(focus: Union[pyannote.core.segment.Segment, Timeline], mode: typing_extensions.Literal['center', 'loose', 'strict'][center, loose, strict] = 'loose', fixed: Optional[float] = None, return_ranges: Optional[bool] = False) → Union[numpy.ndarray, List[List[int]]][source]¶ Crop sliding window
- Parameters:
focus (Segment or Timeline) –
mode ({'strict', 'loose', 'center'}, optional) – In ‘strict’ mode, only indices of segments fully included in ‘focus’ support are returned. In ‘loose’ mode, indices of any intersecting segments are returned. In ‘center’ mode, first and last positions are chosen to be the positions whose centers are the closest to ‘focus’ start and end times. Defaults to ‘loose’.
fixed (float, optional) – Overrides Segment ‘focus’ duration and ensures that the number of returned frames is fixed (which might otherwise not be the case because of rounding erros).
return_ranges (bool, optional) – Return as list of ranges. Defaults to indices numpy array.
- Returns:
indices – Array of unique indices of matching segments
- Return type:
np.array (or list of ranges)
-
property
duration
¶ Sliding window duration in seconds.
-
property
end
¶ Sliding window end time in seconds.
-
range_to_segment
(i0: int, n: int) → pyannote.core.segment.Segment[source]¶ Convert 0-indexed frame range to segment
Each frame represents a unique segment of duration ‘step’, centered on the middle of the frame.
The very first frame (i0 = 0) is the exception. It is extended to the sliding window start time.
- Parameters:
- Returns:
segment
- Return type:
Examples
>>> window = SlidingWindow() >>> print window.range_to_segment(3, 2) [ --> ]
-
samples
(from_duration: float, mode: typing_extensions.Literal['center', 'loose', 'strict'][center, loose, strict] = 'strict') → int[source]¶ Number of frames
- Parameters:
from_duration (float) – Duration in seconds.
mode ({'strict', 'loose', 'center'}) – In ‘strict’ mode, computes the maximum number of consecutive frames that can be fitted into a segment with duration from_duration. In ‘loose’ mode, computes the maximum number of consecutive frames intersecting a segment with duration from_duration. In ‘center’ mode, computes the average number of consecutive frames where the first one is centered on the start time and the last one is centered on the end time of a segment with duration from_duration.
-
segment_to_range
(segment: pyannote.core.segment.Segment) → Tuple[int, int][source]¶ Convert segment to 0-indexed frame range
- Parameters:
segment (Segment) –
- Returns:
i0 (int) – Index of first frame
n (int) – Number of frames
Examples
>>> window = SlidingWindow() >>> print window.segment_to_range(Segment(10, 15)) i0, n
-
property
start
¶ Sliding window start time in seconds.
-
property
step
¶ Sliding window step in seconds.
SlidingWindowFeature¶
-
class
pyannote.core.
SlidingWindowFeature
(data: numpy.ndarray, sliding_window: pyannote.core.segment.SlidingWindow, labels: List[str] = None)[source]¶ Periodic feature vectors
- Parameters:
data ((n_frames, n_features) numpy array) –
sliding_window (SlidingWindow) –
labels (list, optional) – Textual description of each dimension.
-
__init__
(data: numpy.ndarray, sliding_window: pyannote.core.segment.SlidingWindow, labels: List[str] = None)[source]¶ Initialize self. See help(type(self)) for accurate signature.
-
align
(to: pyannote.core.feature.SlidingWindowFeature) → pyannote.core.feature.SlidingWindowFeature[source]¶ Align features by linear temporal interpolation
- Parameters:
to (SlidingWindowFeature) – Features to align with.
- Returns:
aligned – Aligned features
- Return type:
-
crop
(focus: Union[pyannote.core.segment.Segment, pyannote.core.timeline.Timeline], mode: typing_extensions.Literal['center', 'loose', 'strict'][center, loose, strict] = 'loose', fixed: Optional[float] = None, return_data: bool = True) → Union[numpy.ndarray, pyannote.core.feature.SlidingWindowFeature][source]¶ Extract frames
- Parameters:
mode ({'loose', 'strict', 'center'}, optional) – In ‘strict’ mode, only frames fully included in ‘focus’ support are returned. In ‘loose’ mode, any intersecting frames are returned. In ‘center’ mode, first and last frames are chosen to be the ones whose centers are the closest to ‘focus’ start and end times. Defaults to ‘loose’.
fixed (float, optional) – Overrides Segment ‘focus’ duration and ensures that the number of returned frames is fixed (which might otherwise not be the case because of rounding errors).
return_data (bool, optional) – Return a numpy array (default). For Segment ‘focus’, setting it to False will return a SlidingWindowFeature instance.
- Returns:
data – Frame features.
- Return type:
numpy.ndarray or SlidingWindowFeature
See also
-
property
dimension
¶ Dimension of feature vectors
-
iterfeatures
(window: Optional[bool] = False) → Iterator[Union[Tuple[numpy.ndarray, pyannote.core.segment.Segment], numpy.ndarray]][source]¶ Feature vector iterator
- Parameters:
window (bool, optional) – When True, yield both feature vector and corresponding window. Default is to only yield feature vector
Serialization¶
-
pyannote.core.json.
dump
(resource: Union[Segment, Timeline, SlidingWindowFeature, Annotation], fp: TextIO)[source]¶ Serialize
- Parameters:
resource (pyannote.core data structure) – Resource to serialize
fp (file) – File in which resource serialization is written
-
pyannote.core.json.
dump_to
(resource: Union[Segment, Timeline, SlidingWindowFeature, Annotation], path: Union[str, pathlib.Path])[source]¶ Serialize
- Parameters:
resource (pyannote.core data structure) – Resource to serialize
path (string) – Path to file in which resource serialization is written
-
pyannote.core.json.
dumps
(resource: Union[Segment, Timeline, SlidingWindowFeature, Annotation]) → str[source]¶ Serialize to string
- Parameters:
resource (pyannote.core data structure) –
- Returns:
serialization
- Return type:
string
-
pyannote.core.json.
load
(fp: TextIO) → Union[Segment, Timeline, SlidingWindowFeature, Annotation][source]¶ Deserialize
- Parameters:
fp (file) – File containing serialized pyannote.core data structure
- Returns:
deserialized
- Return type:
pyannote.core data structure
-
pyannote.core.json.
load_from
(path: Union[str, pathlib.Path]) → Union[Segment, Timeline, SlidingWindowFeature, Annotation][source]¶ Deserialize
- Parameters:
path (string or Path) – Path to file containing serialized pyannote.core data structure
- Returns:
deserialized
- Return type:
pyannote.core data structure
Visualization¶
Visualization¶
pyannote.core.Segment
,pyannote.core.Timeline
,pyannote.core.Annotation
andpyannote.core.SlidingWindowFeature
instances can be directly visualized in notebooks.You will however need to install
pytannote.core
’s additional dependencies for notebook representations (namely, matplotlib):pip install pyannote.core[notebook]
Segments¶
In [1]: from pyannote.core import Segment In [2]: segment = Segment(start=5, end=15) ....: segment
(Source code, png, hires.png, pdf)
Timelines¶
In [25]: from pyannote.core import Timeline, Segment In [26]: timeline = Timeline() ....: timeline.add(Segment(1, 5)) ....: timeline.add(Segment(6, 8)) ....: timeline.add(Segment(12, 18)) ....: timeline.add(Segment(7, 20)) ....: timeline
(Source code, png, hires.png, pdf)
Annotations¶
In [1]: from pyannote.core import Annotation, Segment In [6]: annotation = Annotation() ...: annotation[Segment(1, 5)] = 'Carol' ...: annotation[Segment(6, 8)] = 'Bob' ...: annotation[Segment(12, 18)] = 'Carol' ...: annotation[Segment(7, 20)] = 'Alice' ...: annotation
(Source code, png, hires.png, pdf)
-
pyannote.core.notebook.
repr_annotation
(annotation: pyannote.core.annotation.Annotation)[source]¶ Get png data for annotation
-
pyannote.core.notebook.
repr_feature
(feature: pyannote.core.feature.SlidingWindowFeature)[source]¶ Get png data for feature
-
-
-
-
-
classmethod
-
classmethod
-
-
-
-
-
-
-
classmethod
-
-
-
-
-
classmethod
-
-
-
-
-