yasa.Hypnogram#

class yasa.Hypnogram(values, n_stages=5, *, freq='30s', start=None, scorer=None, proba=None)#

Experimental class for manipulating hypnogram in YASA (dev).

Starting with v0.7, YASA will take a more object-oriented approach to hypnograms. That is, hypnograms are now stored as a class (aka object), which comes with its own attributes and functions. Furthermore, YASA does not allow integer values to define the stages anymore. Instead, users must pass an array of strings with the actual stage names (e.g. [“WAKE”, “WAKE”, “N1”, …, “REM”, “REM”]).

Added in version 0.7.0.

Parameters:
valuesarray_like

A vector of stage values, represented as strings. See some examples below:

  • 2-stage hypnogram (Wake/Sleep): ["W", "S", "S", "W", "S"]

  • 3-stage (Wake/NREM/REM): pd.Series(["WAKE", "NREM", "NREM", "REM", "REM"])

  • 4-stage (Wake/Light/Deep/REM): np.array(["Wake", "Light", "Deep", "Deep"])

  • 5-stage (default): ["N1", "N1", "N2", "N3", "N2", "REM", "W"]

Artefacts (“Art”) and unscored (“Uns”) epochs are always allowed regardless of the number of stages in the hypnogram.

Note

Abbreviated or full spellings for the stages are allowed, as well as lower/upper/mixed case. Internally, YASA will convert the stages to to full spelling and uppercase (e.g. “w” -> “WAKE”).

n_stagesint

Whether values comes from a 2, 3, 4 or 5-stage hypnogram. Default is 5-stage, meaning that the following sleep stages are allowed: N1, N2, N3, REM, WAKE.

freqstr

A pandas frequency string indicating the frequency resolution of the hypnogram. Default is “30s” meaning that each value in the hypnogram represents a 30-seconds epoch. Examples: “1min”, “10s”, “15min”. A full list of accepted values can be found at https://pandas.pydata.org/docs/user_guide/timeseries.html#timeseries-offset-aliases

freq will be passed to the pandas.date_range function to create the time index of the hypnogram.

startstr or datetime

An optional string indicating the starting datetime of the hypnogram (e.g. “2022-12-15 22:30:00”). If start is specified and valid, the index of the hypnogram will be a pandas.DatetimeIndex. Otherwise it will be a pandas.RangeIndex, indicating the epoch number.

scorerstr

An optional string indicating the scorer name. If specified, this will be set as the name of the pandas.Series, otherwise the name will be set to “Stage”.

probapandas.DataFrame

An optional dataframe with the probability of each sleep stage for each epoch in hypnogram. Each row must sum to 1. This is automatically included if the hypnogram is created with yasa.SleepStaging.

Examples

Create a 2-stage hypnogram

>>> from yasa import Hypnogram
>>> values = ["W", "W", "W", "S", "S", "S", "S", "S", "W", "S", "S", "S"]
>>> hyp = Hypnogram(values, n_stages=2)
>>> hyp
<Hypnogram | 12 epochs x 30s (6.00 minutes), 2 unique stages>
 - Use `.hypno` to get the string values as a pandas.Series
 - Use `.as_int()` to get the integer values as a pandas.Series
 - Use `.plot_hypnogram()` to plot the hypnogram
See the online documentation for more details.

We can access the actual values, which are stored as a pandas.Series, with:

>>> hyp.hypno
Epoch
0      WAKE
1      WAKE
2      WAKE
3     SLEEP
4     SLEEP
5     SLEEP
6     SLEEP
7     SLEEP
8      WAKE
9     SLEEP
10    SLEEP
11    SLEEP
Name: Stage, dtype: category
Categories (4, object): ['WAKE', 'SLEEP', 'ART', 'UNS']
>>> # Number of epochs in the hypnogram
>>> hyp.n_epochs
12
>>> # Total duration of the hypnogram, in minutes (12 epochs * 30 seconds = 6 minutes)
>>> hyp.duration
6.0
>>> # Default mapping from strings to integers. Can be changed with `hyp.mapping = {}`
>>> hyp.mapping
{'WAKE': 0, 'SLEEP': 1, 'ART': -1, 'UNS': -2}
>>> # Get the hypnogram Series integer values
>>> hyp.as_int()
Epoch
0     0
1     0
2     0
3     1
4     1
5     1
6     1
7     1
8     0
9     1
10    1
11    1
Name: Stage, dtype: int16
>>> # Calculate the summary sleep statistics
>>> hyp.sleep_statistics()
{'TIB': 6.0,
 'SPT': 4.5,
 'WASO': 0.5,
 'TST': 4.0,
 'SE': 66.6667,
 'SME': 88.8889,
 'SFI': 7.5,
 'SOL': 1.5,
 'SOL_5min': nan,
 'WAKE': 2.0}
>>> # Get the state-transition matrix
>>> counts, probs = hyp.transition_matrix()
>>> counts
To Stage    WAKE  SLEEP
From Stage
WAKE           2      2
SLEEP          1      6

All these methods and properties are also valid with a 5-stage hypnogram. In the example below, we use the yasa.simulate_hypnogram to generate a plausible 5-stage hypnogram with a 30-seconds resolution. A random seed is specified to ensure that we get reproducible results. Lastly, we set an actual start time to the hypnogram. As a result, the index of the resulting hypnogram is a pandas.DatetimeIndex.

>>> from yasa import simulate_hypnogram
>>> hyp = simulate_hypnogram(
...     tib=500, n_stages=5, start="2022-12-15 22:30:00", scorer="S1", seed=42)
>>> hyp
<Hypnogram | 1000 epochs x 30s (500.00 minutes), 5 unique stages, scored by S1>
 - Use `.hypno` to get the string values as a pandas.Series
 - Use `.as_int()` to get the integer values as a pandas.Series
 - Use `.plot_hypnogram()` to plot the hypnogram
See the online documentation for more details.
>>> hyp.hypno
Time
2022-12-15 22:30:00    WAKE
2022-12-15 22:30:30    WAKE
2022-12-15 22:31:00    WAKE
2022-12-15 22:31:30    WAKE
2022-12-15 22:32:00    WAKE
                    ...
2022-12-16 06:47:30      N2
2022-12-16 06:48:00      N2
2022-12-16 06:48:30      N2
2022-12-16 06:49:00      N2
2022-12-16 06:49:30      N2
Freq: 30S, Name: S1, Length: 1000, dtype: category
Categories (7, object): ['WAKE', 'N1', 'N2', 'N3', 'REM', 'ART', 'UNS']

The summary sleep statistics will include more items with a 5-stage hypnogram than a 2-stage hypnogram, i.e. the amount and percentage of each sleep stage, the REM latency, etc.

>>> hyp.sleep_statistics()
{'TIB': 500.0,
 'SPT': 497.5,
 'WASO': 79.5,
 'TST': 418.0,
 'SE': 83.6,
 'SME': 84.0201,
 'SFI': 0.7177,
 'SOL': 2.5,
 'SOL_5min': 2.5,
 'Lat_REM': 67.0,
 'WAKE': 82.0,
 'N1': 69.0,
 'N2': 247.0,
 'N3': 64.5,
 'REM': 37.5,
 '%N1': 16.5072,
 '%N2': 59.0909,
 '%N3': 15.4306,
 '%REM': 8.9713}
__init__(values, n_stages=5, *, freq='30s', start=None, scorer=None, proba=None)#

Methods

__init__(values[, n_stages, freq, start, ...])

as_events()

Return a pandas DataFrame summarizing epoch-level information.

as_int()

Return hypnogram values as integers.

consolidate_stages(new_n_stages)

Reduce the number of stages in a hypnogram to match actigraphy or wearables.

copy()

Return a new copy of the current Hypnogram.

evaluate(obs_hyp)

Evaluate agreement between two hypnograms of the same sleep session.

find_periods([threshold, equal_length])

Find sequences of consecutive values exceeding a certain duration in hypnogram.

plot_hypnogram(**kwargs)

Plot the hypnogram.

simulate_similar(**kwargs)

Simulate a new hypnogram based on properties of the current hypnogram.

sleep_statistics()

Compute standard sleep statistics from an hypnogram.

transition_matrix()

Create a state-transition matrix from an hypnogram.

upsample(new_freq)

Upsample hypnogram to a higher frequency.

upsample_to_data(data[, sf, verbose])

Upsample an hypnogram to a given sampling frequency and fit the resulting hypnogram to corresponding EEG data, such that the hypnogram and EEG data have the exact same number of samples.

Attributes

duration

Total duration of the hypnogram, expressed in minutes.

freq

The frequency resolution of the hypnogram.

hypno

The hypnogram values, stored in a pandas.Series.

labels

The allowed stage labels.

mapping

A dictionary with the mapping from string to integer values.

mapping_int

A dictionary with the mapping from integer to string values.

n_epochs

The number of epochs in the hypnogram.

n_stages

The number of allowed stages in the hypnogram.

proba

If specified, a pandas.DataFrame with the probability of each sleep stage for each epoch in hypnogram.

sampling_frequency

The sampling frequency (Hz) of the hypnogram.

scorer

The scorer name.

start

The start date/time of the hypnogram.

timedelta

A pandas.TimedeltaIndex vector with the accumulated time difference of each epoch compared to the first epoch.