pynapple.IntervalSet#

class pynapple.IntervalSet(start, end=None, time_units='s', metadata=None)[source]#

Bases: NDArrayOperatorsMixin, _MetadataMixin

A class representing a (irregular) set of time intervals in elapsed time, with relative operations

The IntervalSet object behaves like a numpy ndarray with the limitation that the object is not mutable.

If start and end are not aligned, meaning that:

  1. len(start) != len(end)

  2. end[i] > start[i]

  3. start[i+1] < end[i]

  4. start and end are not sorted,

IntervalSet will try to “fix” the data by eliminating some of the start and end data points.

Parameters:
  • start (numpy.ndarray or number or pandas.DataFrame or pandas.Series or iterable of (start, end) pairs) –

    Beginning of intervals. Alternatively, the end argument can be left out and start can be one of the following:

    • IntervalSet

    • pandas.DataFrame with columns [“start”, “end”]

    • iterable of (start, end) pairs

    • a single (start, end) pair

  • end (numpy.ndarray or number or pandas.Series, optional) – Ends of intervals.

  • time_units (str, optional) – Time unit of the intervals (‘us’, ‘ms’, ‘s’ [default])

  • metadata (pandas.DataFrame or dict, optional) – Metadata associated with each interval. Metadata names are pulled from DataFrame columns or dictionary keys. The length of the metadata should match the length of the intervals.

Raises:

RuntimeError – If start and end arguments are of unknown type.

Examples

Initialize an IntervalSet with a list of start and end times:

>>> import pynapple as nap
>>> import numpy as np
>>> start = [0, 10, 20]
>>> end = [5, 12, 33]
>>> ep = nap.IntervalSet(start=start, end=end)
>>> ep
  index    start    end
      0        0      5
      1       10     12
      2       20     33
shape: (3, 2), time unit: sec.

Initialize an IntervalSet with an array of start and end pairs:

>>> times = np.array([[0, 5], [10, 12], [20, 33]])
>>> ep = nap.IntervalSet(times)
>>> ep
  index    start    end
      0        0      5
      1       10     12
      2       20     33
shape: (3, 2), time unit: sec.

Initialize an IntervalSet with metadata:

>>> start = [0, 10, 20]
>>> end = [5, 12, 33]
>>> metadata = {"label": ["a", "b", "c"]}
>>> ep = nap.IntervalSet(start=start, end=end, metadata=metadata)
  index    start    end     label
      0        0      5     a
      1       10     12     b
      2       20     33     c
shape: (3, 2), time unit: sec.

Initialize an IntervalSet with a pandas DataFrame:

>>> import pandas as pd
>>> df = pd.DataFrame(data={"start": [0, 10, 20], "end": [5, 12, 33], "label": ["a", "b", "c"]})
>>> ep = nap.IntervalSet(df)
>>> ep
  index    start    end     label
      0        0      5     a
      1       10     12     b
      2       20     33     c
shape: (3, 2), time unit: sec.

Apply numpy functions to an IntervalSet:

>>> ep = nap.IntervalSet(start=[0, 10], end=[5,20])
>>> ep
  index    start    end
      0        0      5
      1       10     20
shape: (2, 2), time unit: sec.
>>> np.diff(ep, 1)
UserWarning: Converting IntervalSet to numpy.array
array([[ 5.],
        [10.]])

Slicing an IntervalSet:

>>> ep[:,0]
array([ 0., 10.])
>>> ep[0]
start    end
0        0      5
shape: (1, 2)

Modifying the IntervalSet will raise an error:

>>> ep[0,0] = 1
RuntimeError: IntervalSet is immutable. Starts and ends have been already sorted.
__init__(start, end=None, time_units='s', metadata=None)[source]#

Methods

__init__(start[, end, time_units, metadata])

as_dataframe()

Convert the IntervalSet object to a pandas.DataFrame object.

as_units([units])

returns a pandas DataFrame with time expressed in the desired unit

drop_long_intervals(threshold[, time_units])

Drops the long intervals in the interval set with duration longer than threshold.

drop_short_intervals(threshold[, time_units])

Drops the short intervals in the interval set with duration shorter than threshold.

get_info(key)

Returns metadata based on metadata column name or index.

get_intervals_center([alpha])

Returns by default the centers of each intervals.

in_interval(tsd)

finds out in which element of the interval set each point in a time series fits.

intersect(a)

Set intersection of IntervalSet

merge_close_intervals(threshold[, time_units])

Merges intervals that are very close.

save(filename)

Save IntervalSet object in npz format.

set_diff(a)

set difference of IntervalSet

set_info([metadata])

Add metadata information about the object.

split(interval_size[, time_units])

Split IntervalSet to a new IntervalSet with each interval being of size interval_size.

time_span()

Time span of the interval set.

tot_length([time_units])

Total elapsed time in the set.

union(a)

set union of IntervalSet

Attributes

end

The end times of each interval

ends

Return the ends of the IntervalSet as a Ts object

loc

Slicing function to add compatibility with pandas DataFrame after removing it as a super class of IntervalSet

metadata

Returns a read-only version (copy) of the _metadata DataFrame

metadata_columns

List of metadata column names.

ndim

shape

size

start

The start times of each interval

starts

Return the starts of the IntervalSet as a Ts object

values

Array of start and end times

index

Index of each interval, automatically set from 0 to n_intervals

columns

Column names of the IntervalSet, which are always ["start", "end"]

nap_class

The pynapple class name

metadata_index

Row index for metadata DataFrame.

as_dataframe()[source]#

Convert the IntervalSet object to a pandas.DataFrame object.

Returns:

out – _

Return type:

pandas.DataFrame

as_units(units='s')[source]#

returns a pandas DataFrame with time expressed in the desired unit

Parameters:

units (None, optional) – ‘us’, ‘ms’, or ‘s’ [default]

Returns:

out – DataFrame with adjusted times

Return type:

pandas.DataFrame

columns: ndarray#

Column names of the IntervalSet, which are always [“start”, “end”]

drop_long_intervals(threshold, time_units='s')[source]#

Drops the long intervals in the interval set with duration longer than threshold.

Parameters:
  • threshold (numeric) – Time threshold for “long” intervals

  • time_units (None, optional) – The time units for the treshold (‘us’, ‘ms’, ‘s’ [default])

Returns:

out – A copied IntervalSet with the dropped intervals

Return type:

IntervalSet

drop_short_intervals(threshold, time_units='s')[source]#

Drops the short intervals in the interval set with duration shorter than threshold.

Parameters:
  • threshold (numeric) – Time threshold for “short” intervals

  • time_units (None, optional) – The time units for the treshold (‘us’, ‘ms’, ‘s’ [default])

Returns:

out – A copied IntervalSet with the dropped intervals

Return type:

IntervalSet

property end#

The end times of each interval

property ends#

Return the ends of the IntervalSet as a Ts object

Returns:

The ends of the IntervalSet

Return type:

Ts

get_info(key)[source]#

Returns metadata based on metadata column name or index.

If the metadata name does not contain special nor overlaps with class attributes, it can also be accessed as an attribute.

If the metadata name does not overlap with class-reserved keys, it can also be accessed as a key.

Parameters:

key

  • str: metadata column name or metadata index (for TsdFrame with string column names)

  • list of str: multiple metadata column names or metadata indices (for TsdFrame with string column names)

  • Number: metadata index (for TsGroup and IntervalSet)

  • list, np.ndarray, pd.Series: metadata index (for TsGroup and IntervalSet)

  • tuple: metadata index and column name (for TsGroup and IntervalSet)

Returns:

The metadata information based on the key provided.

Return type:

pandas.Series or pandas.DataFrame or Any (for single location)

Raises:

IndexError – If the metadata index is not found.

Examples

>>> import pynapple as nap
>>> import numpy as np
>>> times = np.array([[0, 5], [10, 12], [20, 33]])
>>> metadata = {"l1": [1, 2, 3], "l2": ["x", "x", "y"]}
>>> ep = nap.IntervalSet(tmp,metadata=metadata)

To access a single metadata column:

>>> ep.get_info("l1")
0    1
1    2
2    3
Name: l1, dtype: int64

To access multiple metadata columns:

>>> ep.get_info(["l1", "l2"])
   l1 l2
0   1  x
1   2  x
2   3  y

To access metadata of a single index:

>>> ep.get_info(0)
rate    0.667223
l1             1
l2             x
Name: 0, dtype: object

To access metadata of multiple indices:

>>> ep.get_info([0, 1])
       rate  l1 l2
0  0.667223   1  x
1  1.334445   2  x

To access metadata of a single index and column:

>>> ep.get_info((0, "l1"))
np.int64(1)

To access metadata as an attribute:

>>> ep.l1
0    1
1    2
2    3
Name: l1, dtype: int64

To access metadata as a key:

>>> ep["l1"]
0    1
1    2
2    3
Name: l1, dtype: int64

Multiple metadata columns can be accessed as keys:

>>> ep[["l1", "l2"]]
   l1 l2
0   1  x
1   2  x
2   3  y
get_intervals_center(alpha=0.5)[source]#

Returns by default the centers of each intervals.

It is possible to bias the midpoint by changing the alpha parameter between [0, 1] For each epoch: t = start + (end-start)*alpha

Parameters:

alpha (float, optional) – The midpoint within each interval.

Returns:

Timestamps object

Return type:

Ts

in_interval(tsd)[source]#

finds out in which element of the interval set each point in a time series fits.

NaNs for those that don’t fit an interval

Parameters:

tsd (Tsd) – The tsd to be binned

Returns:

out – an array with the interval index labels for each time stamp (NaN) for timestamps not in IntervalSet

Return type:

numpy.ndarray

index: ndarray#

Index of each interval, automatically set from 0 to n_intervals

intersect(a)[source]#

Set intersection of IntervalSet

Parameters:

a (IntervalSet) – the IntervalSet to intersect self with

Returns:

out – _

Return type:

IntervalSet

property loc#

Slicing function to add compatibility with pandas DataFrame after removing it as a super class of IntervalSet

merge_close_intervals(threshold, time_units='s')[source]#

Merges intervals that are very close.

Parameters:
  • threshold (numeric) – time threshold for the closeness of the intervals

  • time_units (None, optional) – time units for the threshold (‘us’, ‘ms’, ‘s’ [default])

Returns:

out – a copied IntervalSet with merged intervals

Return type:

IntervalSet

property metadata#

Returns a read-only version (copy) of the _metadata DataFrame

property metadata_columns#

List of metadata column names.

metadata_index: np.ndarray | pd.Index#

Row index for metadata DataFrame. This matches the index for TsGroup and IntervalSet, and the columns for TsdFrame.

nap_class: str#

The pynapple class name

property ndim#
save(filename)[source]#

Save IntervalSet object in npz format. The file will contain the starts and ends.

The main purpose of this function is to save small/medium sized IntervalSet objects. For example, you determined some epochs for one session that you want to save to avoid recomputing them.

You can load the object with nap.load_file. Keys are ‘start’, ‘end’ and ‘type’. See the example below.

Parameters:

filename (str) – The filename

Examples

>>> import pynapple as nap
>>> import numpy as np
>>> ep = nap.IntervalSet(start=[0, 10, 20], end=[5, 12, 33])
>>> ep.save("my_ep.npz")

To load you file, you can use the nap.load_file function :

>>> ep = nap.load_file("my_path/my_ep.npz")
>>> ep
   start   end
0    0.0   5.0
1   10.0  12.0
2   20.0  33.0
Raises:

RuntimeError – If filename is not str, path does not exist or filename is a directory.

set_diff(a)[source]#

set difference of IntervalSet

Parameters:

a (IntervalSet) – the IntervalSet to set-substract from self

Returns:

out – _

Return type:

IntervalSet

set_info(metadata=None, **kwargs)[source]#

Add metadata information about the object. Metadata are saved as a pandas.DataFrame.

If the metadata name does not contain special nor overlaps with class attributes, it can also be set using attribute assignment.

If the metadata name does not overlap with class-reserved keys, it can also be set using key assignment.

Metadata entries (excluding “rate” for TsGroup) are mutable and can be overwritten.

Parameters:
  • metadata (pandas.DataFrame or dict or pandas.Series, optional) –

    Object containing metadata information, where metadata names are extracted from column names (pandas.DataFrame), key names (dict), or index (pandas.DataFrame).

    • If a pandas.DataFrame is passed, the index must match the metadata index.

    • If a dictionary is passed, the length of each value must match the metadata index length.

    • A pandas.Series can only be passed if the object has a single interval.

  • **kwargs (optional) – Key-word arguments for setting metadata. Values can be either pandas.Series, numpy.ndarray, list or tuple, and must have the same length as the metadata index. If pandas.Series, the index must match the metadata index. If the object only has one index, non-iterable values are also accepted.

Raises:
  • ValueError

    • If metadata index does not match input index (pandas.DataFrame, pandas.Series) - If input array length does not match metadata length (numpy.ndarray, list, tuple)

  • RuntimeError – If the metadata argument is passed as a pandas.Series (for more than one metadata index), numpy.ndarray, list or tuple.

  • TypeError – If key-word arguments are not of type pandas.Series, tuple, list, or numpy.ndarray and cannot be set.

Examples

>>> import pynapple as nap
>>> import numpy as np
>>> times = np.array([[0, 5], [10, 12], [20, 33]])
>>> ep = nap.IntervalSet(times)

To add metadata with a pandas.DataFrame:

>>> import pandas as pd
>>> metadata = pd.DataFrame(data=['left','right','left'], columns=['choice'])
>>> ep.set_info(metadata)
>>> ep
  index    start    end     choice
      0        0      5     left
      1       10     12     right
      2       20     33     left
shape: (3, 2), time unit: sec.

To add metadata with a dictionary:

>>> metadata = {"reward": [1, 0, 1]}
>>> ep.set_info(metadata)
>>> ep
  index    start    end     choice      reward
      0        0      5     left             1
      1       10     12     right            0
      2       20     33     left             1
shape: (3, 2), time unit: sec.

To add metadata with a keyword argument (pd.Series, numpy.ndarray, list or tuple):

>>> stim = pd.Series(data = [10, -23, 12])
>>> ep.set_info(stim=stim)
>>> ep
  index    start    end     choice      reward    stim
      0        0      5     left             1      10
      1       10     12     right            0     -23
      2       20     33     left             1      12
shape: (3, 2), time unit: sec.

To add metadata as an attribute:

>>> ep.label = ["a", "b", "c"]
>>> ep
  index    start    end     choice      reward  label
      0        0      5     left             1  a
      1       10     12     right            0  b
      2       20     33     left             1  c
shape: (3, 2), time unit: sec.

To add metadata as a key:

>>> ep["error"] = [0, 0, 0]
>>> ep
  index    start    end     choice      reward  label      error
      0        0      5     left             1  a             0
      1       10     12     right            0  b             0
      2       20     33     left             1  c             0
shape: (3, 2), time unit: sec.

Metadata can be overwritten:

>>> ep.set_info(label=["x", "y", "z"])
>>> ep
  index    start    end     choice      reward  label      error
      0        0      5     left             1  x             0
      1       10     12     right            0  y             0
      2       20     33     left             1  z             0
shape: (3, 2), time unit: sec.
property shape#
property size#
split(interval_size, time_units='s')[source]#

Split IntervalSet to a new IntervalSet with each interval being of size interval_size.

Used mostly for chunking very large dataset or looping throught multiple epoch of same duration.

This function skips the epochs that are shorter than interval_size.

Note that intervals are strictly non-overlapping in pynapple. One microsecond is removed from contiguous intervals.

Parameters:
  • interval_size (Number) – Description

  • time_units (str, optional) – time units for the interval_size (‘us’, ‘ms’, ‘s’ [default])

Returns:

New IntervalSet with equal sized intervals

Return type:

IntervalSet

Raises:

IOError – If interval_size is not a Number or is below 0 If time_units is not a string

property start#

The start times of each interval

property starts#

Return the starts of the IntervalSet as a Ts object

Returns:

The starts of the IntervalSet

Return type:

Ts

time_span()[source]#

Time span of the interval set.

Returns:

out – an IntervalSet with a single interval encompassing the whole IntervalSet

Return type:

IntervalSet

tot_length(time_units='s')[source]#

Total elapsed time in the set.

Parameters:

time_units (None, optional) – The time units to return the result in (‘us’, ‘ms’, ‘s’ [default])

Returns:

out – _

Return type:

float

union(a)[source]#

set union of IntervalSet

Parameters:

a (IntervalSet) – the IntervalSet to union self with

Returns:

out – _

Return type:

IntervalSet

values: ndarray#

Array of start and end times