diff --git a/docs/iris/src/whatsnew/contributions_1.10/newfeature_2016-May-20_lazy_cube_transpose.txt b/docs/iris/src/whatsnew/contributions_1.10/newfeature_2016-May-20_lazy_cube_transpose.txt new file mode 100644 index 0000000000..79e95711bd --- /dev/null +++ b/docs/iris/src/whatsnew/contributions_1.10/newfeature_2016-May-20_lazy_cube_transpose.txt @@ -0,0 +1 @@ +* The transpose method of a Cube now results in a lazy transposed view of the original rather than realising the data then transposing it. diff --git a/lib/iris/cube.py b/lib/iris/cube.py index 0fa492353e..c1853896a5 100644 --- a/lib/iris/cube.py +++ b/lib/iris/cube.py @@ -2802,14 +2802,14 @@ def transpose(self, new_order=None): """ if new_order is None: - new_order = np.arange(self.data.ndim)[::-1] - elif len(new_order) != self.data.ndim: + new_order = np.arange(self.ndim)[::-1] + elif len(new_order) != self.ndim: raise ValueError('Incorrect number of dimensions.') - # The data needs to be copied, otherwise this view of the transposed - # data will not be contiguous. Ensure not to assign via the cube.data - # setter property since we are reshaping the cube payload in-place. - self._my_data = np.transpose(self.data, new_order).copy() + if self.has_lazy_data(): + self._my_data = self.lazy_data().transpose(new_order) + else: + self._my_data = self.data.transpose(new_order) dim_mapping = {src: dest for dest, src in enumerate(new_order)} diff --git a/lib/iris/tests/unit/cube/test_Cube.py b/lib/iris/tests/unit/cube/test_Cube.py index f68214e4f2..fb31d46950 100644 --- a/lib/iris/tests/unit/cube/test_Cube.py +++ b/lib/iris/tests/unit/cube/test_Cube.py @@ -1410,5 +1410,22 @@ def test_fail_cell_measure_dims(self): cm_dims = self.cube.cell_measure_dims(a_cell_measure) +class Test_transpose(tests.IrisTest): + def test_lazy_data(self): + data = np.arange(12).reshape(3, 4) + cube = Cube(biggus.NumpyArrayAdapter(data)) + cube.transpose() + self.assertTrue(cube.has_lazy_data()) + self.assertArrayEqual(data.T, cube.data) + + def test_not_lazy_data(self): + data = np.arange(12).reshape(3, 4) + cube = Cube(data) + cube.transpose() + self.assertFalse(cube.has_lazy_data()) + self.assertIs(data.base, cube.data.base) + self.assertArrayEqual(data.T, cube.data) + + if __name__ == '__main__': tests.main()