docstr: Combine rows with the same key into an accumulator.
  
  This assumes the block is already sorted by key in ascending order.
  
  Args:
      key: A column name or list of column names.
      If this is ``None``, place all rows in a single group.
  
      aggs: The aggregations to do.
  
  Returns:
      A sorted block of [k, v_1, ..., v_n] columns where k is the groupby
      key and v_i is the partially combined accumulator for the ith given
      aggregation.
      If key is None then the k column is omitted.
docstr_tok: ["Combine","rows","with","the","same","key","into","an","accumulator",".","This","assumes","the","block","is","already","sorted","by","key","in","ascending","order",".","Args",":","key",":","A","column","name","or","list","of","column","names",".","If","this","is","``","None","``",",","place","all","rows","in","a","single","group",".","aggs",":","The","aggregations","to","do",".","Returns",":","A","sorted","block","of","[","k",",","v_1",",","...",",","v_n","]","columns","where","k","is","the","groupby","key","and","v_i","is","the","partially","combined","accumulator","for","the","ith","given","aggregation",".","If","key","is","None","then","the","k","column","is","omitted","."]
code: def combine(
      self, key: Union[str, List[str]], aggs: Tuple["AggregateFn"]
  ) -> "pandas.DataFrame":
      """Combine rows with the same key into an accumulator.
  
      This assumes the block is already sorted by key in ascending order.
  
      Args:
          key: A column name or list of column names.
          If this is ``None``, place all rows in a single group.
  
          aggs: The aggregations to do.
  
      Returns:
          A sorted block of [k, v_1, ..., v_n] columns where k is the groupby
          key and v_i is the partially combined accumulator for the ith given
          aggregation.
          If key is None then the k column is omitted.
      """
      if key is not None and not isinstance(key, (str, list)):
          raise ValueError(
              "key must be a string, list of strings or None when aggregating "
              "on Pandas blocks, but "
              f"got: {type(key)}."
          )
  
      def iter_groups() -> Iterator[Tuple[KeyType, Block]]:
          """Creates an iterator over zero-copy group views."""
          if key is None:
              # Global aggregation consists of a single "group", so we short-circuit.
              yield None, self.to_block()
              return
  
          start = end = 0
          iter = self.iter_rows(public_row_format=False)
          next_row = None
          while True:
              try:
                  if next_row is None:
                      next_row = next(iter)
                  next_key = next_row[key]
                  while np.all(next_row[key] == next_key):
                      end += 1
                      try:
                          next_row = next(iter)
                      except StopIteration:
                          next_row = None
                          break
                  yield next_key, self.slice(start, end, copy=False)
                  start = end
              except StopIteration:
                  break
  
      builder = PandasBlockBuilder()
      for group_key, group_view in iter_groups():
          # Aggregate.
          accumulators = [agg.init(group_key) for agg in aggs]
          for i in range(len(aggs)):
              accumulators[i] = aggs[i].accumulate_block(
                  accumulators[i], group_view
              )
  
          # Build the row.
          row = {}
          if key is not None:
              if isinstance(key, list):
                  keys = key
                  group_keys = group_key
              else:
                  keys = [key]
                  group_keys = [group_key]
  
              for k, gk in zip(keys, group_keys):
                  row[k] = gk
  
          count = collections.defaultdict(int)
          for agg, accumulator in zip(aggs, accumulators):
              name = agg.name
              # Check for conflicts with existing aggregation name.
              if count[name] > 0:
                  name = self._munge_conflict(name, count[name])
              count[name] += 1
              row[name] = accumulator
  
          builder.add(row)
  
      return builder.build()
  
imports: import collections
  import heapq
  from typing import TYPE_CHECKING, Any, Callable, Dict, Iterator, List, Optional, Tuple, TypeVar, Union
  import numpy
  from ray.air.constants import TENSOR_COLUMN_NAME
  from ray.data._internal.table_block import TableBlockAccessor, TableBlockBuilder
  from ray.data._internal.util import find_partitions
  from ray.data.block import Block, BlockAccessor, BlockExecStats, BlockMetadata, KeyType, U
  from ray.data.context import DataContext
  from ray.data.row import TableRow
label_desc: Use image node_id 27 for calling the PandasBlockAccessor obj's underlying member method code with example usage: obj.combine(key, aggs) and returns: builder