utilities.arrays.apply_ufunc_to_labels#

utilities.arrays.apply_ufunc_to_labels(ufunc: ufunc, method: str, *inputs: Tuple[Tuple[Sequence[int], Sequence[str] | None], ...], **kwargs)[source]#

Infer the output shape and axis labels of a ufunc applied to labeled input shapes.

This function simulates the structural behavior of NumPy ufuncs while tracking axis labels across operations. It is designed to work alongside tensor-aware data structures like labeled fields, where axis semantics must be preserved or transformed according to the broadcasting and reduction rules of NumPy.

Parameters:
  • ufunc (np.ufunc) – The NumPy ufunc being applied (e.g., np.add, np.multiply, np.sum).

  • method (str) – The method being invoked on the ufunc, such as ‘__call__’, ‘reduce’, ‘reduceat’, ‘accumulate’, ‘outer’, or ‘at’.

  • *inputs

    One or more (shape, label) pairs.

    • shape must be a sequence of integers representing the array shape.

    • labels must be a sequence of strings or None with the same length as the shape, or None to indicate an unlabeled input.

  • **kwargs

    Additional keyword arguments specific to the ufunc method:

    • axis : int or tuple of int (for ‘reduce’, ‘reduceat’)

    • keepdims : bool (for ‘reduce’)

    • indices : sequence of int (for ‘reduceat’)

Returns:

  • output_shape (tuple of int) – The resulting shape after applying the ufunc method.

  • output_labels (tuple of str or None) – The axis labels associated with the resulting shape. Labels are propagated from inputs where possible, with singleton-suppression and axis elimination rules enforced appropriately.

Raises:
  • ValueError – If the number of inputs is inconsistent with the ufunc arity or method requirements, or if required keyword arguments are missing or malformed.

  • NotImplementedError – If the requested ufunc method is not supported or not defined on the given ufunc.

Examples

>>> apply_ufunc_to_labels(np.add, '__call__',
...     ((3, 1, 4), ['x', 'y', 'z']),
...     ((1, 5, 4), [None, 'y', 'z']))
((3, 5, 4), ('x', 'y', 'z'))
>>> apply_ufunc_to_labels(np.add, 'reduce',
...     ((3, 4, 5), ['x', 'y', 'z']),
...     axis=1, keepdims=False)
((3, 5), ('x', 'z'))
>>> apply_ufunc_to_labels(np.add, 'outer',
...     ((3,), ['x']),
...     ((4,), ['y']))
((3, 4), ('x', 'y'))