Source code for improver.utilities.indexing_operations
# (C) Crown Copyright, Met Office. All rights reserved.
#
# This file is part of 'IMPROVER' and is released under the BSD 3-Clause license.
# See LICENSE in the root of the repository for full licensing details.
"""Module to contain indexing operation functions."""
import numpy as np
from numpy import ndarray
[docs]
def choose(index_array: ndarray, array_set: ndarray) -> ndarray:
"""
Create a reordered copy of a data array, where an index array of matching
shape determines how the data is reordered.
The reordered copy of the array will have the same shape as the inputs.
If a 3-dimensional array_set is provided, the data coordinates could be
described as A[i, j, k]. This function does not rearrange the j and k
coordinates. The reordered array is constructed by substituting into each
position [i, j, k] in the index_array a value taken from the array_set
at a matching [j, k] position, but where [i] is determined by the given
index value. As such the index values must run 0 - N-1 where N is the
length of the leading dimension of array_set (and equivalently of
index_array).
The following figure gives an examples of the expected result of this
function for a given index_array and array_set.
.. figure:: extended_documentation/utilities/indexing_operations/
numpy_choose_test1.png
:align: center
:scale: 60 %
:alt: Diagram to help explain indexing behaviour of choose.
The input data array is reordered along the leading dimension (i),
but maintains its sub-array position (j, k), denoted here by the
different colours.
Args:
index_array:
This array must contain integers in the range [0, N-1], where N is
if the length of the leading dimension of the array_set array.
These integers determine how array_set will be reordered in the
returned array.
array_set:
A multi-dimensional array, where the leading dimension is in effect
an indexing dimension. Within this leading dimension are the
sub-arrays from which values are to be extracted at positions that
match those given in the index_array.
Returns:
An array containing the reordered data extracted from array_set.
The returned array will have the same shape as the index_array and
array_set arrays.
Raises:
ValueError: If index_array and array_set do not have matching shapes.
IndexError: If an index exceeds the length of the leading dimension
of the array_set array (N-1).
"""
if index_array.shape != array_set.shape:
msg = (
"The choose function only works with an index_array that "
"matches the shape of array_set.\nindex_array shape: {}\n"
"array_set shape: {}".format(index_array.shape, array_set.shape)
)
raise ValueError(msg)
if index_array.max() > array_set.shape[0] - 1:
msg = (
"index_array contains an index that is larger than the "
"number of sub-arrays from which data can be drawn.\nMax "
"index: {}\nNumber of sub-arrays: {}".format(
index_array.max(), array_set.shape[0]
)
)
raise IndexError(msg)
result = np.array(
[array_set[index_array[i]][i[1:]] for i in np.ndindex(index_array.shape)]
).reshape(index_array.shape)
return result