class_docstr: Operator for merging part of an array into another one
  
  Parameters
  ----------
  axis: None or int or tuple of ints
      the axis (or axes) on which the merge will happen. This axis will be split into 3 parts: the first and last one will take
      value from the first array, the middle one from the second array.
  max_size: None or int
      maximum size of the part taken from the second array. By default, this is at most around half the number of total elements of the
      array to the power of 1/number of axis.
  
  
  Notes
  -----
  - this is experimental, the API may evolve
  - when using several axis, the size of the second array part is the same on each axis (aka a square in 2D, a cube in 3D, ...)
  
  Examples:
  ---------
  - 2-dimensional array, with crossover on dimension 1:
    0 1 0 0
    0 1 0 0
    0 1 0 0
  - 2-dimensional array, with crossover on dimensions 0 and 1:
    0 0 0 0
    0 1 1 0
    0 1 1 0
code: def _apply_array(self, arrays: tp.Sequence[np.ndarray]) -> np.ndarray:
      root = self.root()
      # checks
      if len(arrays) != 2:
          raise Exception(
              f"Crossover can only be applied between 2 individuals, got {len(arrays)}"
          )
      transf = (
          transforms.Fourrier(
              range(arrays[0].ndim) if self.axis is None else self.axis
          )
          if root.parameters["fft"].value
          else None
      )
      if transf is not None:
          arrays = [transf.forward(a) for a in arrays]
      shape = arrays[0].shape
      assert (
          shape == arrays[1].shape
      ), "Individuals should have the same shape"
      # settings
      axis = (
          tuple(range(len(shape))) if self.axis is None else self.axis
      )
      max_size = root.parameters["max_size"].value
      max_size = (
          int(((arrays[0].size + 1) / 2) ** (1 / len(axis)))
          if max_size is None
          else max_size
      )
      max_size = min(max_size, *(shape[a] - 1 for a in axis))
      size = (
          1 if max_size == 1 else self.random_state.randint(1, max_size)
      )
      # slices
      slices = _make_slices(shape, axis, size, self.random_state)
      result = np.array(arrays[0], copy=True)
      result[tuple(slices)] = arrays[1][tuple(slices)]
      if transf is not None:
          result = transf.backward(result)
      return result
  
imports: import typing
  import numpy
  from .None import core
  from .None import transforms
  from .data import Data, Scalar
  from .choice import Choice
  from .None import _layering
label_desc: Use image node_id 4 for calling the Crossover obj's underlying member method code with example usage: obj._apply_array(arrays) and returns: result