geowatch.utils.util_kwutil module

Functions that may be moved to kwutil

geowatch.utils.util_kwutil.distributed_subitems(items, max_num=None)[source]

Return a subset of items maximally distributed over the input index space. I.e. the chosen indexes maximize the space between them.

Parameters:

items (List | Dict) – an ordered indexable object

Returns:

a subset of the input with a length at most max_num.

Return type:

List | Dict

Note

Prefer using the generator variant farthest_first() instead.

Todo

  • [X] Find a better name. ChatGPT suggests using “spread”, which I

    like. Maybe spreadsort, spreadshuffle, spredtraverse? spreadtake, takespread?

  • [ ] Figure out where this lives, probably kwutil.

  • [X] maybe we should force this to be a generator? Or make a generator variant?

Example

>>> from geowatch.utils.util_kwutil import *  # NOQA
>>> items = list(range(100))
>>> max_num = 5
>>> sub_items = distributed_subitems(items, max_num)
>>> print(sub_items)
[0, 25, 50, 75, 99]

Example

>>> from geowatch.utils.util_kwutil import *  # NOQA
>>> items = {chr(i): i for i in range(ord('a'), ord('a') + 26)}
>>> max_num = 5
>>> sub_items = distributed_subitems(items, max_num)
>>> print(sub_items)
{'a': 97, 'g': 103, 'n': 110, 't': 116, 'z': 122}
geowatch.utils.util_kwutil.farthest_first(items, max_num=None, first=None)[source]

Return a subset of items maximally distributed over the input index space. I.e. the chosen indexes maximize the space between them.

Parameters:
  • items (List | Dict) – an ordered indexable object

  • first (int | None) – if specified, start with this index.

Returns:

a subset of the input with a length at most max_num.

Return type:

List | Dict

Note

A farthest first sequence is not unique in general. The particular order this function returns may change in the future.

Example

>>> from geowatch.utils.util_kwutil import *  # NOQA
>>> items = list(range(100))
>>> max_num = 5
>>> sub_items = list(farthest_first(items, max_num))
>>> print(list(sub_items))
[99, 0, 50, 25, 75]

Example

>>> from geowatch.utils.util_kwutil import *  # NOQA
>>> items = {chr(i): i for i in range(ord('a'), ord('a') + 26)}
>>> max_num = 5
>>> sub_items = list(farthest_first(items, max_num))
>>> print(dict(sub_items))
{'z': 122, 'a': 97, 'n': 110, 'g': 103, 't': 116}

Example

>>> # Choose a custom starting location
>>> from geowatch.utils.util_kwutil import *  # NOQA
>>> import ubelt as ub
>>> items = list(range(10))
>>> results = []
>>> start, stop = 0, 10
>>> for first in range(start, stop):
>>>     results += [list(farthest_first(items, first=first))]
>>> print(f'results = {ub.urepr(results, nl=1)}')
results = [
    [0, 9, 4, 2, 6, 1, 3, 5, 7, 8],
    [1, 9, 5, 3, 7, 0, 2, 4, 6, 8],
    [2, 9, 5, 0, 7, 1, 3, 4, 6, 8],
    [3, 9, 0, 6, 1, 2, 4, 5, 7, 8],
    [4, 9, 0, 2, 6, 1, 3, 5, 7, 8],
    [5, 0, 9, 2, 7, 1, 3, 4, 6, 8],
    [6, 0, 3, 9, 1, 2, 4, 5, 7, 8],
    [7, 0, 3, 5, 9, 1, 2, 4, 6, 8],
    [8, 0, 4, 2, 6, 1, 3, 5, 7, 9],
    [9, 0, 5, 2, 7, 1, 6, 3, 8, 4],
]