コード例 #1
0
 def test_unmatched_array_shapes(self):
     """Test that a useful error is raised when the index_array and
     data_array have different shapes. This choose function provides only
     a subset of the full numpy choose features, and one of its limitations
     is to work only with arrays that match; there is no broadcasting."""
     index_array = np.array([[[0, 1], [1, 0]], [[0, 2], [0, 1]]])
     msg = ("The choose function only works with an index_array that "
            "matches the shape of array_set.")
     with self.assertRaisesRegex(ValueError, msg):
         choose(index_array, self.small_data)
コード例 #2
0
 def test_invalid_array_indices(self):
     """Test that a useful error is raised when the array that is indexed
     to provide data does not exist because the index is out of range. More
     simply, if there are only 3 sub-arays, indices of 3 or more should lead
     to a sensbile error. Note that the behaviour of this function is
     equivalent to numpy choose with mode=raise, there is no attempt to wrap
     or clip invalid index values."""
     index_array = np.array([[[0, 1], [1, 0]], [[0, 2], [0, 1]],
                             [[3, 3], [3, 3]]])
     msg = "index_array contains an index that is larger than the number"
     with self.assertRaisesRegex(IndexError, msg):
         choose(index_array, self.small_data)
コード例 #3
0
 def test_numpy_choose_comparison_3D_index_array_test2(self):
     """Test that a 3D array of indices with a shape matching the data array
     returns the same result as numpy choose. Here the sub-arrays are
     rearranged as complete units."""
     index_array = np.array([[[1, 1], [1, 1]], [[2, 2], [2, 2]],
                             [[0, 0], [0, 0]]])
     choose_result = choose(index_array, self.small_data)
     npchoose_result = np.choose(index_array, self.small_data)
     self.assertArrayEqual(choose_result, npchoose_result)
     self.assertEqual(choose_result.shape, npchoose_result.shape)
コード例 #4
0
 def test_numpy_choose_comparison_3D_index_array_test1(self):
     """Test that a 3D array of indices with a shape matching the data array
     returns the same result as numpy choose. Here values are taken from a
     mix of sub-arrays."""
     index_array = np.array([[[0, 1], [1, 0]], [[0, 2], [0, 1]],
                             [[1, 1], [2, 0]]])
     choose_result = choose(index_array, self.small_data)
     npchoose_result = np.choose(index_array, self.small_data)
     self.assertArrayEqual(choose_result, npchoose_result)
     self.assertEqual(choose_result.shape, npchoose_result.shape)
コード例 #5
0
 def test_3D_index_array_utilising_indices_beyond_32(self):
     """An explicit test that this function is handling indices beyond 32.
     The numpy choose function does not support a data array with a leading
     dimension of longer than 32. Note that due to indexing from 0, an index
     of 32 here is for array 33, beyond numpy's limit."""
     index_array = np.ones(self.data.shape).astype(int)
     expected = np.array([self.data[1]] * 33)
     result = choose(index_array, self.data)
     self.assertArrayEqual(result, expected)
     self.assertEqual(result.shape, expected.shape)
コード例 #6
0
 def test_3D_index_array_test2(self):
     """Test that a 3D array of indices with a shape matching the data array
     returns the expected values. Here the sub-arrays are rearranged as
     complete units."""
     index_array = np.array([[[1, 1], [1, 1]], [[2, 2], [2, 2]],
                             [[0, 0], [0, 0]]])
     expected = np.array(
         [self.small_data[1], self.small_data[2], self.small_data[0]])
     result = choose(index_array, self.small_data)
     self.assertArrayEqual(result, expected)
     self.assertEqual(result.shape, expected.shape)
コード例 #7
0
 def test_3D_index_array_test1(self):
     """Test that a 3D array of indices with a shape matching the data array
     returns the expected values. Here values are taken from a mix of
     sub-arrays. This example can be seen graphically in the documentation
     for the choose function."""
     index_array = np.array([[[0, 1], [1, 0]], [[0, 2], [0, 1]],
                             [[1, 1], [2, 0]]])
     expected = np.array([[[1, 6], [7, 4]], [[1, 10], [3, 8]],
                          [[5, 6], [11, 4]]])
     result = choose(index_array, self.small_data)
     self.assertArrayEqual(result, expected)
     self.assertEqual(result.shape, expected.shape)
コード例 #8
0
    def rank_ecc(post_processed_forecast_percentiles,
                 raw_forecast_realizations,
                 random_ordering=False,
                 random_seed=None):
        """
        Function to apply Ensemble Copula Coupling. This ranks the
        post-processed forecast realizations based on a ranking determined from
        the raw forecast realizations.

        Args:
            post_processed_forecast_percentiles (cube):
                Cube for post-processed percentiles. The percentiles are
                assumed to be in ascending order.
            raw_forecast_realizations (cube):
                Cube containing the raw (not post-processed) forecasts.
                The probabilistic dimension is assumed to be the zeroth
                dimension.
            random_ordering (Logical):
                If random_ordering is True, the post-processed forecasts are
                reordered randomly, rather than using the ordering of the
                raw ensemble.
            random_seed (Integer or None):
                If random_seed is an integer, the integer value is used for
                the random seed.
                If random_seed is None, no random seed is set, so the random
                values generated are not reproducible.

        Returns:
            iris.cube.Cube:
                Cube for post-processed realizations where at a particular grid
                point, the ranking of the values within the ensemble matches
                the ranking from the raw ensemble.

        """
        results = iris.cube.CubeList([])
        for rawfc, calfc in zip(
                raw_forecast_realizations.slices_over("time"),
                post_processed_forecast_percentiles.slices_over("time")):
            if random_seed is not None:
                random_seed = int(random_seed)
            random_seed = np.random.RandomState(random_seed)
            random_data = random_seed.rand(*rawfc.data.shape)
            if random_ordering:
                # Returns the indices that would sort the array.
                # As these indices are from a random dataset, only an argsort
                # is used.
                ranking = np.argsort(random_data, axis=0)
            else:
                # Lexsort returns the indices sorted firstly by the
                # primary key, the raw forecast data (unless random_ordering
                # is enabled), and secondly by the secondary key, an array of
                # random data, in order to split tied values randomly.
                sorting_index = np.lexsort((random_data, rawfc.data), axis=0)
                # Returns the indices that would sort the array.
                ranking = np.argsort(sorting_index, axis=0)
            # Index the post-processed forecast data using the ranking array.
            # The following uses a custom choose function that reproduces the
            # required elements of the np.choose method without the limitation
            # of having < 32 arrays or a leading dimension < 32 in the
            # input data array. This function allows indexing of a 3d array
            # using a 3d array.
            calfc.data = choose(ranking, calfc.data)
            results.append(calfc)
        # Ensure we haven't lost any dimensional coordinates with only one
        # value in.
        results = results.merge_cube()
        results = check_cube_coordinates(post_processed_forecast_percentiles,
                                         results)
        return results