docstr: Adapter for Pandas DataFrames in long format, where different time series for the same id are
  labeled by column `column_kind`.
  
  :param df: the data frame
  :type df: pd.DataFrame
  
  :param column_id: the name of the column containing time series group ids
  :type column_id: str
  
  :param column_kind: the name of the column containing time series kinds for each id
  :type column_kind: str
  
  :param column_value: None or the name of the column containing time series values
      If `None`, try to guess it from the remaining, unused columns.
  :type column_value: str|None
  
  :param column_sort: the name of the column to sort on
  :type column_sort: str|None
code: def __init__(
      self,
      df,
      column_id,
      column_kind,
      column_value=None,
      column_sort=None,
  ):
      """
      Adapter for Pandas DataFrames in long format, where different time series for the same id are
      labeled by column `column_kind`.
  
      :param df: the data frame
      :type df: pd.DataFrame
  
      :param column_id: the name of the column containing time series group ids
      :type column_id: str
  
      :param column_kind: the name of the column containing time series kinds for each id
      :type column_kind: str
  
      :param column_value: None or the name of the column containing time series values
          If `None`, try to guess it from the remaining, unused columns.
      :type column_value: str|None
  
      :param column_sort: the name of the column to sort on
      :type column_sort: str|None
      """
      if column_id is None:
          raise ValueError("A value for column_id needs to be supplied")
      if column_kind is None:
          raise ValueError(
              "A value for column_kind needs to be supplied"
          )
  
      if column_value is None:
          possible_value_columns = _get_value_columns(
              df, column_id, column_sort, column_kind
          )
          if len(possible_value_columns) != 1:
              raise ValueError(
                  "Could not guess the value column, as the number of unused columns os not equal to 1."
                  f"These columns where currently unused: {','.join(possible_value_columns)}"
                  "Please hand it to the function as an argument."
              )
          self.column_value = possible_value_columns[0]
      else:
          self.column_value = column_value
  
      _check_nan(df, column_id, column_kind, self.column_value)
  
      if column_sort is not None:
          _check_nan(df, column_sort)
  
      self.column_sort = column_sort
      self.df_grouped = df.groupby([column_id, column_kind])
  
      super().__init__(df, column_id)
  
imports: import itertools
  from collections import defaultdict, namedtuple
  from typing import Iterable, Sized
  import pandas
label_desc: Use image node_id 1 to create a new LongTsFrameAdapter object from inherited base classes: PartitionedTsData with example: obj = LongTsFrameAdapter(df, column_id, column_kind, column_value, column_sort)