diff --git a/src/hist/basehist.py b/src/hist/basehist.py index cc008b7a..de19f9e8 100644 --- a/src/hist/basehist.py +++ b/src/hist/basehist.py @@ -204,6 +204,10 @@ def project(self, *args: int | str) -> Self | float | bh.accumulators.Accumulato int_args = [self._name_to_index(a) if isinstance(a, str) else a for a in args] return super().project(*int_args) + @property + def T(self) -> Self: + return self.project(*reversed(range(self.ndim))) # type: ignore[return-value] + def fill( self, *args: ArrayLike, diff --git a/tests/test_general.py b/tests/test_general.py index 092a3262..ecce3225 100644 --- a/tests/test_general.py +++ b/tests/test_general.py @@ -953,3 +953,48 @@ def test_integrate(): assert h1[{"x": 4j}] == 2 assert h1[{"x": 2j}] == 1 assert h2[{"x": 1j}] == 3 + + +def test_T_property(): + # Create a 2D histogram with some data + hist_data = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) + h = hist.Hist( + hist.axis.Regular(3, 0, 1, flow=False), + hist.axis.Regular(3, 5, 6, flow=False), + data=hist_data, + ) + + assert h.T.values() == approx(h.values().T) + assert h.T.axes[0] == h.axes[1] + assert h.T.axes[1] == h.axes[0] + + +def test_T_empty(): + hist_empty = hist.Hist() + hist_T_empty = hist_empty.T + assert hist_empty == hist_T_empty + + +def test_T_1D(): + # Create a 1D histogram with some data + hist_data_1D = np.array([1, 2, 3, 4, 5]) + h_1D = hist.Hist(hist.axis.Regular(5, 0, 1, flow=False), data=hist_data_1D) + + assert h_1D.T.values() == approx(h_1D.values().T) + assert h_1D.T.axes[0] == h_1D.axes[0] + + +def test_T_3D(): + # Create a 3D histogram with some data + hist_data_3D = np.random.rand(1, 3, 4) + h_3D = hist.Hist( + hist.axis.Regular(2, 0, 1, flow=False), + hist.axis.Regular(3, 2, 3, flow=False), + hist.axis.Regular(4, 5, 6, flow=False), + data=hist_data_3D, + ) + + assert h_3D.T.values() == approx(h_3D.values().T) + assert h_3D.T.axes[0] == h_3D.axes[2] + assert h_3D.T.axes[1] == h_3D.axes[1] + assert h_3D.T.axes[2] == h_3D.axes[0]