code: def manual_shuffle(self, axis, shuffle_func, lengths):
          
          if axis:
              partitions = self.row_partitions
          else:
              partitions = self.column_partitions
          func = self.preprocess_func(shuffle_func)
          result = np.array([part.shuffle(func, lengths) for part in partitions])
          return self.__constructor__(result) if axis else self.__constructor__(result.T)
docs: Shuffle the partitions based on the `shuffle_func`.
  
          Args:
              axis: The axis to shuffle across.
              shuffle_func: The function to apply before splitting the result.
              lengths: The length of each partition to split the result into.
  
          Returns:
               A new BaseFrameManager object, the type of object that called this.