code: def to_events(
      labels: Union[pd.Series, pd.DataFrame],
      freq_as_period: bool = True,
      merge_consecutive: Optional[bool] = None,
  ) -> Union[
      List[Union[Tuple[pd.Timestamp, pd.Timestamp], pd.Timestamp]],
      Dict[
          str,
          List[Union[Tuple[pd.Timestamp, pd.Timestamp], pd.Timestamp]],
      ],
  ]:
      """Convert binary label series to event list.
  
      Parameters
      ----------
      labels: pandas Series or DataFrame
          Binary series of anomaly labels. If a DataFrame, each column is
          regarded as a type of anomaly independently.
  
      freq_as_period: bool, optional
          Whether to regard time index with regular frequency (i.e. attribute
          `freq` of time index is not None) as time intervals.
  
          For example, DatetimeIndex(['2017-01-01', '2017-01-02', '2017-01-03',
          '2017-01-04', '2017-01-05'], dtype='datetime64[ns]', freq='D') has
          daily frequency. If freq_as_period=True, each time point in the index
          represents that day (24 hours). Otherwsie, each time point represents
          the instantaneous time instance of 00:00:00 on that day.
  
          Default: True.
  
      merge_consecutive: bool, optional
          Whether to merge consecutive events into a single time window. If not
          specified, it is on automatically if the input time index has a regular
          frequency and freq_as_period=True, and it is off otherwise. Default:
          None.
  
      Returns
      -------
      list or dict
          - If input is a Series, output is a list of events where an event is a
            pandas Timestamp if it is instantaneous or a 2-tuple of pandas
            Timestamps if it is a closed time interval.
          - If input is a DataFrame, every column is treated as an independent
            binary series, and output is a dict where keys are column names and
            values are event lists.
  
      """
  
      if isinstance(labels, pd.Series):
          labels = validate_series(
              labels, check_freq=False, check_categorical=False
          )
          labels = labels == 1
  
          if merge_consecutive is None:
              if freq_as_period and (labels.index.freq is not None):
                  merge_consecutive = True
              else:
                  merge_consecutive = False
  
          if not merge_consecutive:
              if freq_as_period and (labels.index.freq is not None):
                  period_end = pd.date_range(
                      start=labels.index[1],
                      periods=len(labels.index),
                      freq=labels.index.freq,
                  ) - pd.Timedelta(
                      "1ns"
                  )  # type: pd.DatetimeIndex
                  return [
                      (start, end) if start != end else start
                      for start, end in zip(
                          list(labels.index[labels]),
                          list(period_end[labels]),
                      )
                  ]
              else:
                  return list(labels.index[labels])
          else:
              labels_values = labels.values.astype(int).reshape(
                  -1, 1
              )  # type: np.ndarray
              mydiff = np.vstack(
                  [
                      labels_values[0, :] - 0,
                      np.diff(labels_values, axis=0),
                      0 - labels_values[-1, :],
                  ]
              )  # type: np.ndarray
              starts = np.argwhere(mydiff == 1)  # type: np.ndarray
              ends = np.argwhere(mydiff == -1)  # type: np.ndarray
              if freq_as_period and (labels.index.freq is not None):
                  period_end = pd.date_range(
                      start=labels.index[1],
                      periods=len(labels.index),
                      freq=labels.index.freq,
                  ) - pd.Timedelta("1ns")
                  return [
                      (labels.index[start], period_end[end - 1])
                      if labels.index[start] != period_end[end - 1]
                      else labels.index[start]
                      for start, end in zip(starts[:, 0], ends[:, 0])
                  ]
              else:
                  return [
                      (labels.index[start], labels.index[end - 1])
                      if start != end - 1
                      else labels.index[start]
                      for start, end in zip(starts[:, 0], ends[:, 0])
                  ]
      else:
          if labels.columns.duplicated().any():
              raise ValueError(
                  "Input DataFrame must have unique column names."
              )
          return {
              col: to_events(
                  labels[col], freq_as_period, merge_consecutive
              )
              for col in labels.columns
          }
  
file_path: adtk/src/adtk/data/_data.py
imports: from typing import Dict, List, Optional, Tuple, Union, overload
  import numpy
  import pandas
label_desc: Use image node_id 5 for calling a global function with example usage: to_events(labels, freq_as_period, merge_consecutive) and returns: unknown, unknown, list, unknown, unknown