code: def apply(
          self,
          func,
          num_splits=None,
          other_axis_partition=None,
          maintain_partitioning=True,
          **kwargs
      ):
          
          import dask
  
          if num_splits is None:
              num_splits = len(self.list_of_blocks)
  
          if other_axis_partition is not None:
              return [
                  DaskFramePartition(dask.delayed(obj))
                  for obj in deploy_func_between_two_axis_partitions(
                      self.axis,
                      func,
                      num_splits,
                      len(self.list_of_blocks),
                      kwargs,
                      *dask.compute(
                          *tuple(
                              self.list_of_blocks + other_axis_partition.list_of_blocks
                          )
                      )
                  )
              ]
  
          args = [self.axis, func, num_splits, kwargs, maintain_partitioning]
  
          args.extend(dask.compute(*self.list_of_blocks))
          return [
              DaskFramePartition(dask.delayed(obj)) for obj in deploy_axis_func(*args)
          ]
docs: Applies func to the object.
  
          See notes in Parent class about this method.
  
          Args:
              func: The function to apply.
              num_splits: The number of times to split the result object.
              other_axis_partition: Another `DaskFrameAxisPartition` object to apply to
                  func with this one.
  
          Returns:
              A list of `DaskFramePartition` objects.