shape#

named_arrays.shape(a)#

Compute the shape of the given array.

In numpy, the shape of an array is a tuple of integers. For this package, each axis is characterized by a name instead of its position, so the shape is a dict where the keys are the axis names and the values are number of elements along each axis.

If a is an arbitrarily-nested structure (dict, list, tuple, or dataclasses instance), the result is the broadcast_shapes() of the shapes of all the array-like leaves, so a container of compatible arrays reports their combined broadcasted shape.

A dataclass which defines its own shape is believed rather than walked. This is for objects carrying arrays which they are not themselves shaped by, a table of measurements they were fitted against being the usual case: such a table is sampled along an axis of its own, which has nothing to say about the shape of the object holding it and need not agree with the axes of any other table alongside it. Inheriting shape from named_arrays.mixins.Indexable is not defining one, since that is this function.

Parameters:

a (int | float | complex | ndarray | Quantity | AbstractArray) – The array, or nested structure of arrays, to compute the shape of.

Return type:

dict[str, int]

Examples

import named_arrays as na

x = na.arange(0, 5, axis="x")
y = na.arange(0, 3, axis="y")

# the broadcasted shape of every array-like leaf
na.shape({"foo": x, "bar": y})
{'x': 5, 'y': 3}

A dataclass which says what its shape is, is believed.

import dataclasses

@dataclasses.dataclass
class Detector:
    gain: na.AbstractScalar
    measurement: na.AbstractScalar

    @property
    def shape(self) -> dict[str, int]:
        # the measurement was fitted against, not sampled by, this
        return na.shape(self.gain)

detector = Detector(
    gain=na.arange(0, 4, axis="channel"),
    measurement=na.arange(0, 100, axis="wavelength"),
)

na.shape(detector)
{'channel': 4}