verde.rolling_window

verde.rolling_window(coordinates, size, spacing=None, shape=None, region=None, adjust='spacing')[source]

Select points on a rolling (moving) window.

A window of the given size is moved across the region at a given step (specified by spacing or shape). Returns the indices of points falling inside each window step. You can use the indices to select points falling inside a given window.

The size of the step when moving the windows can be specified by the spacing parameter. Alternatively, the number of windows in the South-North and West-East directions can be specified using the shape parameter. One of the two must be given.

Parameters
  • coordinates (tuple of arrays) – Arrays with the coordinates of each data point. Should be in the following order: (easting, northing, vertical, …). Only easting and northing will be used, all subsequent coordinates will be ignored.

  • size (float) – The size of the windows. Units should match the units of coordinates.

  • spacing (float, tuple = (s_north, s_east), or None) – The window size in the South-North and West-East directions, respectively. A single value means that the size is equal in both directions.

  • shape (tuple = (n_north, n_east) or None) – The number of blocks in the South-North and West-East directions, respectively.

  • region (list = [W, E, S, N]) – The boundaries of a given region in Cartesian or geographic coordinates. If not region is given, will use the bounding region of the given points.

  • adjust ({'spacing', 'region'}) – Whether to adjust the spacing or the region if required. Ignored if shape is given instead of spacing. Defaults to adjusting the spacing.

Returns

  • window_coordinates (tuple of arrays) – Coordinate arrays for the center of each window.

  • indices (array) – Each element of the array corresponds the indices of points falling inside a window. The array will have the same shape as the window_coordinates. Use the array elements to index the coordinates for each window. The indices will depend on the number of dimensions in the input coordinates. For example, if the coordinates are 2D arrays, each window will contain indices for 2 dimensions (row, column).

See also

block_split

Split a region into blocks and label points accordingly.

expanding_window

Select points on windows of changing size.

Examples

Generate a set of sample coordinates on a grid and determine the indices of points for each rolling window:

>>> from verde import grid_coordinates
>>> coords = grid_coordinates((-5, -1, 6, 10), spacing=1)
>>> print(coords[0])
[[-5. -4. -3. -2. -1.]
 [-5. -4. -3. -2. -1.]
 [-5. -4. -3. -2. -1.]
 [-5. -4. -3. -2. -1.]
 [-5. -4. -3. -2. -1.]]
>>> print(coords[1])
[[ 6.  6.  6.  6.  6.]
 [ 7.  7.  7.  7.  7.]
 [ 8.  8.  8.  8.  8.]
 [ 9.  9.  9.  9.  9.]
 [10. 10. 10. 10. 10.]]
>>> # Get the rolling window indices
>>> window_coords, indices = rolling_window(coords, size=2, spacing=2)
>>> # Window coordinates will be 2D arrays. Their shape is the number of
>>> # windows in each dimension
>>> print(window_coords[0].shape, window_coords[1].shape)
(2, 2) (2, 2)
>>> # The there are the easting and northing coordinates for the center of
>>> # each rolling window
>>> for coord in window_coords:
...     print(coord)
[[-4. -2.]
 [-4. -2.]]
[[7. 7.]
 [9. 9.]]
>>> # The indices of points falling on each window will have the same shape
>>> # as the window center coordinates
>>> print(indices.shape)
(2, 2)
>>> # The points in the first window. Indices are 2D positions because the
>>> # coordinate arrays are 2D.
>>> print(len(indices[0, 0]))
2
>>> for dimension in indices[0, 0]:
...     print(dimension)
[0 0 0 1 1 1 2 2 2]
[0 1 2 0 1 2 0 1 2]
>>> for dimension in indices[0, 1]:
...     print(dimension)
[0 0 0 1 1 1 2 2 2]
[2 3 4 2 3 4 2 3 4]
>>> for dimension in indices[1, 0]:
...     print(dimension)
[2 2 2 3 3 3 4 4 4]
[0 1 2 0 1 2 0 1 2]
>>> for dimension in indices[1, 1]:
...     print(dimension)
[2 2 2 3 3 3 4 4 4]
[2 3 4 2 3 4 2 3 4]
>>> # To get the coordinates for each window, use indexing
>>> print(coords[0][indices[0, 0]])
[-5. -4. -3. -5. -4. -3. -5. -4. -3.]
>>> print(coords[1][indices[0, 0]])
[6. 6. 6. 7. 7. 7. 8. 8. 8.]

If the coordinates are 1D, the indices will also be 1D:

>>> coords1d = [coord.ravel() for coord in coords]
>>> window_coords, indices = rolling_window(coords1d, size=2, spacing=2)
>>> print(len(indices[0, 0]))
1
>>> print(indices[0, 0][0])
[ 0  1  2  5  6  7 10 11 12]
>>> print(indices[0, 1][0])
[ 2  3  4  7  8  9 12 13 14]
>>> print(indices[1, 0][0])
[10 11 12 15 16 17 20 21 22]
>>> print(indices[1, 1][0])
[12 13 14 17 18 19 22 23 24]
>>> # The returned indices can be used in the same way as before
>>> print(coords1d[0][indices[0, 0]])
[-5. -4. -3. -5. -4. -3. -5. -4. -3.]
>>> print(coords1d[1][indices[0, 0]])
[6. 6. 6. 7. 7. 7. 8. 8. 8.]

By default, the windows will span the entire data region. You can also control the specific region you’d like the windows to cover:

>>> # Coordinates on a larger region but with the same spacing as before
>>> coords = grid_coordinates((-10, 5, 0, 20), spacing=1)
>>> # Get the rolling window indices but limited to the region from before
>>> window_coords, indices = rolling_window(
...     coords, size=2, spacing=2, region=(-5, -1, 6, 10),
... )
>>> # The windows should still be in the same place as before
>>> for coord in window_coords:
...     print(coord)
[[-4. -2.]
 [-4. -2.]]
[[7. 7.]
 [9. 9.]]
>>> # And indexing the coordinates should also provide the same result
>>> print(coords[0][indices[0, 0]])
[-5. -4. -3. -5. -4. -3. -5. -4. -3.]
>>> print(coords[1][indices[0, 0]])
[6. 6. 6. 7. 7. 7. 8. 8. 8.]

Only the first 2 coordinates are considered (assumed to be the horizontal ones). All others will be ignored by the function.

>>> coords = grid_coordinates((-5, -1, 6, 10), spacing=1, extra_coords=20)
>>> print(coords[2])
[[20. 20. 20. 20. 20.]
 [20. 20. 20. 20. 20.]
 [20. 20. 20. 20. 20.]
 [20. 20. 20. 20. 20.]
 [20. 20. 20. 20. 20.]]
>>> window_coords, indices = rolling_window(coords, size=2, spacing=2)
>>> # The windows would be the same in this case since coords[2] is ignored
>>> for coord in window_coords:
...     print(coord)
[[-4. -2.]
 [-4. -2.]]
[[7. 7.]
 [9. 9.]]
>>> print(indices.shape)
(2, 2)
>>> for dimension in indices[0, 0]:
...     print(dimension)
[0 0 0 1 1 1 2 2 2]
[0 1 2 0 1 2 0 1 2]
>>> for dimension in indices[0, 1]:
...     print(dimension)
[0 0 0 1 1 1 2 2 2]
[2 3 4 2 3 4 2 3 4]
>>> for dimension in indices[1, 0]:
...     print(dimension)
[2 2 2 3 3 3 4 4 4]
[0 1 2 0 1 2 0 1 2]
>>> for dimension in indices[1, 1]:
...     print(dimension)
[2 2 2 3 3 3 4 4 4]
[2 3 4 2 3 4 2 3 4]
>>> # The indices can still be used with the third coordinate
>>> print(coords[0][indices[0, 0]])
[-5. -4. -3. -5. -4. -3. -5. -4. -3.]
>>> print(coords[1][indices[0, 0]])
[6. 6. 6. 7. 7. 7. 8. 8. 8.]
>>> print(coords[2][indices[0, 0]])
[20. 20. 20. 20. 20. 20. 20. 20. 20.]