class_docstr: Splits a string tensor into bytes.
class_docstr_tok: ["Splits","a","string","tensor","into","bytes","."]
docstr: Splits a string tensor into sub-strings.
  
  The strings are split based upon the provided byte offsets.
  
  Example:
  
  >>> splitter = ByteSplitter()
  >>> substrings = splitter.split_by_offsets("hello", [0, 4], [4, 5])
  >>> print(substrings.numpy())
  [b'hell' b'o']
  
  Args:
    input: `Tensor` or `RaggedTensor` of strings of any shape to split.
    start_offsets: `Tensor` or `RaggedTensor` of byte offsets to start splits
        on (inclusive). This should be one more than the rank of `input`.
    end_offsets: `Tensor` or `RaggedTensor` of byte offsets to end splits
        on (exclusive). This should be one more than the rank of `input`.
  
  Returns:
    A `RaggedTensor` or `Tensor` of substrings. The returned shape is the
    shape of the offsets.
docstr_tok: ["Splits","a","string","tensor","into","sub-strings",".","The","strings","are","split","based","upon","the","provided","byte","offsets",".","Example",":",">",">",">","splitter","=","ByteSplitter","(",")",">",">",">","substrings","=","splitter.split_by_offsets","(","``","hello","''",",","[","0",",","4","]",",","[","4",",","5","]",")",">",">",">","print","(","substrings.numpy","(",")",")","[","b'hell","'","b","'","o","'","]","Args",":","input",":","`","Tensor","`","or","`","RaggedTensor","`","of","strings","of","any","shape","to","split",".","start_offsets",":","`","Tensor","`","or","`","RaggedTensor","`","of","byte","offsets","to","start","splits","on","(","inclusive",")",".","This","should","be","one","more","than","the","rank","of","`","input","`",".","end_offsets",":","`","Tensor","`","or","`","RaggedTensor","`","of","byte","offsets","to","end","splits","on","(","exclusive",")",".","This","should","be","one","more","than","the","rank","of","`","input","`",".","Returns",":","A","`","RaggedTensor","`","or","`","Tensor","`","of","substrings",".","The","returned","shape","is","the","shape","of","the","offsets","."]
code: def split_by_offsets(
      self, input, start_offsets, end_offsets
  ):  # pylint: disable=redefined-builtin
      """Splits a string tensor into sub-strings.
  
      The strings are split based upon the provided byte offsets.
  
      Example:
  
      >>> splitter = ByteSplitter()
      >>> substrings = splitter.split_by_offsets("hello", [0, 4], [4, 5])
      >>> print(substrings.numpy())
      [b'hell' b'o']
  
      Args:
        input: `Tensor` or `RaggedTensor` of strings of any shape to split.
        start_offsets: `Tensor` or `RaggedTensor` of byte offsets to start splits
            on (inclusive). This should be one more than the rank of `input`.
        end_offsets: `Tensor` or `RaggedTensor` of byte offsets to end splits
            on (exclusive). This should be one more than the rank of `input`.
  
      Returns:
        A `RaggedTensor` or `Tensor` of substrings. The returned shape is the
        shape of the offsets.
      """
      name = None
      with ops.name_scope(
          name,
          "ByteSplitByOffsets",
          [input, start_offsets, end_offsets],
      ):
          input_tensor = (
              ragged_tensor.convert_to_tensor_or_ragged_tensor(input)
          )
          starts = ragged_tensor.convert_to_tensor_or_ragged_tensor(
              start_offsets
          )
          ends = ragged_tensor.convert_to_tensor_or_ragged_tensor(
              end_offsets
          )
          if input_tensor.shape.ndims is None:
              raise ValueError(
                  "Rank of input_tensor must be statically known."
              )
          if starts.shape.ndims is None:
              raise ValueError(
                  "Rank of start_offsets must be statically known."
              )
          if ends.shape.ndims is None:
              raise ValueError(
                  "Rank of end_offsets must be statically known."
              )
          if starts.shape.ndims != ends.shape.ndims:
              raise ValueError(
                  "Rank of start_offsets should be the same as ends."
              )
          if starts.shape.ndims != input_tensor.shape.ndims + 1:
              raise ValueError(
                  "Rank of offsets should be the as input values."
              )
          if ragged_tensor.is_ragged(input_tensor):
              if not ragged_tensor.is_ragged(starts):
                  starts = ragged_conversion_ops.from_tensor(starts)
              if not ragged_tensor.is_ragged(ends):
                  ends = ragged_conversion_ops.from_tensor(ends)
              if input_tensor.flat_values.shape.ndims > 1:
                  # TODO(broken): Handle case where ragged_rank are not equal.
                  if (
                      starts.ragged_rank != input_tensor.ragged_rank
                      or ends.ragged_rank != input_tensor.ragged_rank
                  ):
                      raise ValueError(
                          "Ragged rank of inputs must be the same."
                      )
                  # If the flat_values of our ragged tensor is multi-dimensional, we can
                  # process it separately and our output will have the same nested
                  # splits as our input.
                  result = self.split_by_offsets(
                      input_tensor.flat_values,
                      starts.flat_values,
                      ends.flat_values,
                  )
                  return input_tensor.with_flat_values(result)
              else:
                  # Recursively process the values of the ragged tensor.
                  result = self.split_by_offsets(
                      input_tensor.values, starts.values, ends.values
                  )
                  return input_tensor.with_values(result)
          else:
              if input_tensor.shape.ndims > 1:
                  # Convert the input tensor to ragged and process it.
                  input_tensor = ragged_conversion_ops.from_tensor(
                      input_tensor
                  )
                  return self.split_by_offsets(
                      input_tensor, starts, ends
                  )
              elif input_tensor.shape.ndims == 0:
                  stacked_inputs = array_ops_stack.stack([input_tensor])
                  stacked_starts = array_ops_stack.stack([starts])
                  stacked_ends = array_ops_stack.stack([ends])
                  result = self.split_by_offsets(
                      stacked_inputs, stacked_starts, stacked_ends
                  )
                  return result.values
              else:
                  # Our rank 1 tensor is the correct shape, so we can process it as
                  # normal.
                  if not ragged_tensor.is_ragged(starts):
                      starts = ragged_conversion_ops.from_tensor(starts)
                  if not ragged_tensor.is_ragged(ends):
                      ends = ragged_conversion_ops.from_tensor(ends)
                  (
                      values,
                      splits,
                  ) = gen_byte_splitter.tf_text_byte_split_by_offsets(
                      input_tensor,
                      starts.values,
                      ends.values,
                      starts.row_splits,
                  )
                  return RaggedTensor.from_nested_row_splits(
                      values, [splits]
                  )
  
file_path: text/tensorflow_text/python/ops/byte_splitter.py
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  from tensorflow.python.eager import monitoring
  from tensorflow.python.framework import ops
  from tensorflow.python.ops import array_ops_stack
  from tensorflow.python.ops.ragged import ragged_conversion_ops
  from tensorflow.python.ops.ragged import ragged_tensor
  from tensorflow.python.ops.ragged.ragged_tensor import RaggedTensor
  from tensorflow_text.python.ops.tokenization import SplitterWithOffsets
  from tensorflow.python.framework import load_library
  from tensorflow.python.platform import resource_loader
label_desc: Use image node_id 5 for calling the ByteSplitter obj's underlying member method code with example usage: obj.split_by_offsets(input, start_offsets, end_offsets) and returns: input_tensor, input_tensor, self, result, RaggedTensor